% !Mode:: "TeX:UTF-8"
% Translator: Yujun Li 
\chapter{\glsentrytext{deep_model}中的优化}
\label{chap:optimization_for_training_deep_models}
% 267 head
\gls{DL}算法在许多情况下都涉及到优化。
例如，模型中的进行推断（如\,\glssymbol{PCA}）涉及到求解优化问题。
我们经常使用解析优化去证明或设计算法。
在\gls{DL}涉及到的诸多优化问题中，最难的是\gls{NN}训练。
甚至是用几百台机器投入几天到几个月来解决单个\gls{NN}训练问题，也是很常见的。
因为这其中的优化问题很重要，代价也很高，因此研究者们开发了一组专门为此设计的优化技术。
本章会介绍\gls{NN}训练中的这些优化技术。

% 267 mid
如果你不熟悉基于梯度优化的基本原则，我们建议回顾\chapref{chap:numerical_computation}。
该章简要概述了一般的\gls{nume_optimization}。


本章主要关注这一类特定的优化问题：寻找\gls{NN}上的一组参数$\Vtheta$，它能显著地降低\gls{cost_function} $J(\Vtheta)$，该\gls{cost_function}通常包括整个\gls{training_set}上的性能评估和额外的\gls{regularization}项。
% 267 mid


首先，我们会介绍在\gls{ML}任务中作为训练算法使用的优化与纯优化有哪些不同。
接下来，我们会介绍导致\gls{NN}优化困难的几个具体挑战。
然后，我们会介绍几个实用算法，包括优化算法本身和初始化参数的策略。
更高级的算法能够在训练中自适应调整\gls{learning_rate}，或者使用\gls{cost_function}二阶导数包含的信息。
最后，我们会介绍几个将简单优化算法结合成高级过程的优化策略，以此作为总结。
% 268 head


\section{学习和纯优化有什么不同}
\label{sec:how_learning_differs_from_pure_optimization}
用于\gls{deep_model}训练的优化算法与传统的优化算法在几个方面有所不同。
\gls{ML}通常是间接作用的。
在大多数\gls{ML}问题中，我们关注某些性能度量$P$，其定义于\gls{test_set}上并且可能是不可解的。
因此，我们只是间接地优化$P$。
我们希望通过降低\gls{cost_function} $J(\Vtheta)$来提高$P$。
这一点与纯优化不同，纯优化最小化目标$J$本身。
训练\gls{deep_model}的优化算法通常也会包括一些针对\gls{ML}\gls{objective_function}的特定结构进行的特化。
% 268 mid


通常，\gls{cost_function}可写为\gls{training_set}上的平均，如
\begin{equation}
\label{eq:8.1}
    J(\Vtheta) = \SetE_{(\RVx, \RSy) \sim\hat{p}_\text{data}} L(f(\Vx ; \Vtheta), y), % ??
\end{equation}
其中$L$是每个样本的\gls{loss_function}，$f(\Vx;\Vtheta)$是输入$\Vx$时所预测的输出，$\hat{p}_{\text{data}}$是\gls{empirical_distribution}。
\gls{supervised_learning}中，$y$是目标输出。
在本章中，我们会介绍不带\gls{regularization}的\gls{supervised}学习，$L$的变量是$f(\Vx;\Vtheta)$和$y$。
不难将这种\gls{supervised_learning}扩展成其他形式，如包括$\Vtheta$或者$\Vx$作为参数，或是去掉参数$y$，以发展不同形式的\gls{regularization}或是\gls{unsupervised_learning}。
% 268 mid


\eqnref{eq:8.1}定义了\gls{training_set}上的\gls{objective_function}。
通常，我们更希望最小化取自\emph{\gls{DGD}}\,$p_{\text{data}}$的期望，而不仅仅是有限\gls{training_set}上的对应\gls{objective_function}：
\begin{equation}
\label{eq:8.2}
    J^*(\Vtheta) = \SetE_{(\RVx, \RSy) \sim p_\text{data}} L(f(\Vx ;\Vtheta),y). % ??
\end{equation}
% 268 end


\subsection{\glsentrytext{empirical_risk_minimization}}
\label{sec:empirical_risk_minimization}
\gls{ML}算法的目标是降低\eqnref{eq:8.2}所示的期望\gls{generalization_error}。
这个数据量被称为\firstgls{risk}。
在这里，我们强调该期望取自真实的\gls{underlying}分布$p_{\text{data}}$。
如果我们知道了真实分布$p_{\text{data}}(\Vx, y)$，那么最小化风险变成了一个可以被优化算法解决的优化问题。
然而，我们遇到的\gls{ML}问题，通常是不知道$p_\text{data}(\Vx, y)$，只知道\gls{training_set}中的样本。
% 269 head


将\gls{ML}问题转化回一个优化问题的最简单方法是最小化\gls{training_set}上的期望损失。
这意味着用\gls{training_set}上的\gls{empirical_distribution}\,$\hat{p}(\Vx,y)$替代真实分布$p(\Vx,y)$。
现在，我们将最小化\firstgls{empirical_risk}：
\begin{equation}
\label{eq:8.3}
    \SetE_{\RVx, \RSy \sim \hat{p}_\text{data}} [L(f(\Vx ; \Vtheta), y)] % ?? \RVx
    = \frac{1}{m} \sum_{i=1}^m L( f(\Vx^{(i)}; \Vtheta), y^{(i)}) ,
\end{equation}
其中$m$表示训练样本的数目。
% 269 mid


基于最小化这种平均\gls{training_error}的训练过程被称为\firstgls{empirical_risk_minimization}。
在这种情况下，\gls{ML}仍然和传统的直接优化很相似。
我们并不直接最优化\gls{risk}，而是最优化\gls{empirical_risk}，希望也能够很大地降低\gls{risk}。
一系列不同的理论构造了一些条件，使得在这些条件下真实\gls{risk}的期望可以下降不同的量。
% 269 mid


然而，\gls{empirical_risk_minimization}很容易导致\gls{overfitting}。
高\gls{capacity}的模型会简单地记住\gls{training_set}。
在很多情况下，\gls{empirical_risk_minimization}并非真的可行。
最有效的现代优化算法是基于\gls{GD}的，但是很多有用的\gls{loss_function}，如$0-1$损失，没有有效的导数（导数要么为零，要么处处未定义）。
这两个问题说明，在\gls{DL}中我们很少使用\gls{empirical_risk_minimization}。
反之，我们会使用一个稍有不同的方法，我们真正优化的目标会更加不同于我们希望优化的目标。
% 269 end


\subsection{\glsentrytext{surrogate_loss_function}和\glsentrytext{early_stopping}}
\label{sec:surrogate_loss_functions_and_early_stopping}
% 269 end
有时，我们真正关心的\gls{loss_function}（比如分类误差）并不能被高效地优化。
例如，即使对于\gls{linear_classifier}而言，精确地最小化$0-1$损失通常是不可解的（复杂度是输入维数的指数级别）\citep{Marcotte-92}。
在这种情况下，我们通常会优化\firstgls{surrogate_loss_function}。
\gls{surrogate_loss_function}作为原目标的代理，还具备一些优点。  
例如，正确类别的负对数似然通常用作$0-1$损失的替代。
负对数似然允许模型估计给定样本的类别的条件概率，如果该模型效果好，那么它能够输出期望最小分类误差所对应的类别。
% 270 head


在某些情况下，\gls{surrogate_loss_function}比原函数学到的更多。
例如，使用对数似然替代函数时，在\gls{training_set}上的$0-1$损失达到$0$之后，\gls{test_set}上的$0-1$损失还能持续下降很长一段时间。
这是因为即使$0-1$损失期望是零时，我们还能拉开不同类别的距离以改进分类器的鲁棒性，获得一个更强壮的、更值得信赖的分类器，从而，相对于简单地最小化\gls{training_set}上的平均$0-1$损失，它能够从训练数据中抽取更多信息。
% 270 head


一般的优化和我们用于训练算法的优化有一个重要不同：训练算法通常不会停止在\gls{local_minimum}。
反之，\gls{ML}通常优化\gls{surrogate_loss_function}，但是在基于\gls{early_stopping}（\secref{sec:early_stopping}）的收敛条件满足时停止。
通常，\gls{early_stopping}使用真实\gls{underlying}\gls{loss_function}，如\gls{validation_set}上的$0-1$损失，并设计为在\gls{overfitting}发生之前终止。
与纯优化不同的是，\gls{early_stopping}时\gls{surrogate_loss_function}仍然有较大的导数，而纯优化终止时导数较小。
% 270 mid


\subsection{\gls{batch}算法和\gls{minibatch}算法}
\label{sec:batch_and_minibatch_algorithms}
\gls{ML}算法和一般优化算法不同的一点是，\gls{ML}算法的\gls{objective_function}通常可以分解为训练样本上的求和。
%\gls{ML}优化算法通常使用整个\gls{cost_function}中的一部分项去更新其参数。
\gls{ML}中的优化算法在计算参数的每一次更新时通常仅使用整个\gls{cost_function}中一部分项来估计\gls{cost_function}的期望值。
% 270 mid

例如，\gls{maximum_likelihood_estimation}问题可以在对数空间中分解成各个样本的总和：
\begin{equation}
\label{eq:8.4}
    \Vtheta_{\text{ML}} = \underset{\Vtheta}{\argmax} \sum_{i=1}^m
    \log p_{\text{model}} (\Vx^{(i)}, y^{(i)}; \Vtheta) .
\end{equation}
% 270 mid


最大化这个总和等价于最大化\gls{training_set}在\gls{empirical_distribution}上的期望：
\begin{equation}
\label{eq:8.5}
    J(\Vtheta) = \SetE_{\RVx, \RSy \sim\hat{p}_\text{data}} 
    \log p_{\text{model}} (\Vx,y ; \Vtheta) .
\end{equation}
%  270 end


优化算法用到的\gls{objective_function}$J$中的大多数属性也是\gls{training_set}上的期望。
例如，最常用的属性是梯度：
\begin{equation}
\label{eq:8.6}
    \nabla_{\Vtheta} J(\Vtheta) = \SetE_{\RVx, \RSy \sim\hat{p}_{\text{data}}} 
    \nabla_{\Vtheta} \log p_{\text{model}} (\Vx,y; \Vtheta) .
\end{equation}
%  271 head


准确计算这个期望的计算代价非常大，因为我们需要在整个数据集上的每个样本上评估模型。
在实践中，我们可以从数据集中随机采样少量的样本，然后计算这些样本上的平均值。
%  271 head


回想一下，$n$个样本均值的\gls{standard_error}（\eqnref{eq:5.46}）是$\sigma/\sqrt{n}$，其中$\sigma$是样本值真实的\gls{standard_deviation}。
分母$\sqrt{n}$表明使用更多样本来估计梯度的方法的回报是低于线性的。
比较两个假想的梯度计算，一个基于$100$个样本，另一个基于$10,000$个样本。
后者需要的计算量是前者的$100$倍，但却只降低了$10$倍的均值\gls{standard_error}。
如果能够快速地计算出梯度估计值，而不是缓慢地计算准确值，那么大多数优化算法会收敛地更快（就总的计算量而言，而不是指更新次数）。
%  271 mid


另一个促使我们从小数目样本中获得梯度的统计估计的动机是\gls{training_set}的冗余。
在最坏的情况下，\gls{training_set}中所有的$m$个样本都是彼此相同的拷贝。
基于采样的梯度估计可以使用单个样本计算出正确的梯度，而比原来的做法少花了$m$倍时间。
实践中，我们不太可能真的遇到这种最坏情况，但我们可能会发现大量样本都对梯度做出了非常相似的贡献。

使用整个\gls{training_set}的优化算法被称为\firstgls{batch}或\firstgls{deterministic}梯度算法，因为它们会在一个大\gls{batch}中同时处理所有样本。
这个术语可能有点令人困惑，因为这个词``\gls{batch}''也经常被用来描述\gls{minibatch}\gls{SGD}算法中用到的\gls{minibatch}样本。
通常，术语``\gls{batch}\gls{GD}''指使用全部\gls{training_set}，而术语``\gls{batch}''单独出现时指一组样本。
例如，我们普遍使用术语``\gls{batch}大小''表示\gls{minibatch}的大小。
%  271 mid


每次只使用单个样本的优化算法有时被称为\firstgls{stochastic}或者\firstgls{online}算法。
术语``\gls{online}''通常是指从连续产生样本的数据流中抽取样本的情况，而不是从一个固定大小的\gls{training_set}中遍历多次采样的情况。
%  271 end


% 272 head
大多数用于\gls{DL}的算法介于以上两者之间，使用一个以上，而又不是全部的训练样本。
传统上，这些会被称为\firstgls{minibatch}或\firstgls{minibatch_stochastic}方法 ，现在通常将它们简单地称为\firstgls{stochastic}方法。


随机方法的典型示例是\gls{SGD}，这将在\secref{sec:stochastic_gradient_descent_chap8}中详细描述。
% 272 mid

\gls{minibatch}的大小通常由以下几个因素决定：
\begin{itemize}
    \item 更大的\gls{batch}会计算更精确的梯度估计，但是回报却是小于线性的。
    
    \item 极小\gls{batch}通常难以充分利用多核架构。
    这促使我们使用一些绝对最小\gls{batch}，低于这个值的小\gls{batch}处理不会减少计算时间。
    
    \item 如果\gls{batch}处理中的所有样本可以并行地处理（通常确是如此），那么内存消耗和\gls{batch}大小会正比。
    对于很多硬件设施，这是\gls{batch}大小的限制因素。
    
    \item 在某些硬件上使用特定大小的数组时，运行时间会更少。
    尤其是在使用\,\glssymbol{GPU}\,时，通常使用$2$的幂数作为\gls{batch}大小可以获得更少的运行时间。
    一般，$2$的幂数的取值范围是$32$到$256$，$16$有时在尝试大模型时使用。
% 272 mid    
    \item 
    可能是由于小\gls{batch}在学习过程中加入了\gls{noise}，它们会有一些\gls{regularize}效果~\citep{Wilson-2003}。
    \gls{generalization_error}通常在\gls{batch}大小为$1$时最好。
    因为梯度估计的高方差，小\gls{batch}训练需要较小的\gls{learning_rate}以保持稳定性。
    因为降低的\gls{learning_rate}和消耗更多步骤来遍历整个\gls{training_set}都会产生更多的步骤，所以会导致总的运行时间非常大。
\end{itemize}
% 272 mid


不同的算法使用不同的方法从\gls{minibatch}中获取不同的信息。
有些算法对采样误差比其他算法更敏感，这通常有两个可能原因。
一个是它们使用了很难在少量样本上精确估计的信息，另一个是它们以放大采样误差的方式使用了信息。
仅基于梯度$\Vg$的更新方法通常相对鲁棒，并能使用较小的\gls{batch}获得成功，如$100$。
使用\gls{hessian}矩阵$\MH$，计算如$\MH^{-1}\Vg$更新的二阶方法通常需要更大的\gls{batch}，如$10,000$。
这些大\gls{batch}需要最小化估计$\MH^{-1}\Vg$的波动。
假设$\MH$被精确估计，但是有\gls{poor_conditioning}数。
乘以$\MH$或是其逆会放大之前存在的误差（这个示例中是指$\Vg$的估计误差）。
即使$\MH$被精确估计，$\Vg$中非常小的变化也会导致更新值$\MH^{-1}\Vg$中非常大的变化。
当然，我们通常只会近似地估计$\MH$，因此相对于我们使用具有较差条件的操作去估计$\Vg$，更新$\MH^{-1}\Vg$会含有更多的误差。
% 273 head

% 273 head
\gls{minibatch}是随机抽取的这点也很重要。
从一组样本中计算出梯度期望的\gls{unbiased}估计要求这些样本是独立的。
我们也希望两个连续的梯度估计是互相独立的，因此两个连续的\gls{minibatch}样本也应该是彼此独立的。
很多现实的数据集自然排列，从而使得连续的样本之间具有高度相关性。
例如，假设我们有一个很长的血液样本测试结果清单。
清单上的数据有可能是这样获取的，头五个血液样本于不同时间段取自第一个病人，接下来三个血液样本取自第二个病人，再随后的血液样本取自第三个病人，等等。
如果我们从这个清单上顺序抽取样本，那么我们的每个\gls{minibatch}数据的偏差都很大，因为这个\gls{minibatch}很可能只代表着数据集上众多患者中的某一个患者。
在这种数据集中的顺序有很大影响的情况下，很有必要在抽取\gls{minibatch}样本前打乱样本顺序。
对于非常大的数据集，如数据中心含有几十亿样本的数据集，我们每次构建\gls{minibatch}样本时都将样本完全均匀地抽取出来是不太现实的。
幸运的是，实践中通常将样本顺序打乱一次，然后按照这个顺序存储起来就足够了。
之后训练模型时会用到的一组组\gls{minibatch}连续样本是固定的，每个独立的模型每次遍历训练数据时都会重复使用这个顺序。
然而，这种偏离真实随机采样的方法并没有很严重的有害影响。
不以某种方式打乱样本顺序才会极大地降低算法的性能。
% 273 mid


很多\gls{ML}上的优化问题都可以分解成并行地计算不同样本上单独的更新。
换言之，我们在计算\gls{minibatch}样本$\MX$上最小化$J(\MX)$的更新时，同时可以计算其他\gls{minibatch}样本上的更新。
这类\gls{asynchronous}并行分布式方法将在\secref{sec:large_scale_distributed_implementations}中进一步讨论。
% 273 end


\gls{minibatch}\gls{SGD}的一个有趣动机是，只要没有重复使用样本，
它将遵循着真实\emph{\gls{generalization_error}}（\eqnref{eq:8.2}）的梯度。
很多\gls{minibatch}\gls{SGD}方法的实现都会打乱数据顺序一次，然后多次遍历数据来更新参数。
第一次遍历时，每个\gls{minibatch}样本都用来计算真实\gls{generalization_error}的\gls{unbiased}估计。
第二次遍历时，估计将会是\gls{biased}的，因为它重新抽取了已经用过的样本，而不是从和原先样本相同的\gls{DGD}中获取新的无偏的样本。
%  274 head


我们不难从\gls{online_learning}的情况中看出\gls{SGD}最小化\gls{generalization_error}的原因。
这时样本或者\gls{minibatch}都是从数据\firstgls{stream}中抽取出来的。
换言之，\gls{learner}好像是一个每次看到新样本的人，
每个样本$(\Vx,y)$都来自\gls{DGD}~$p_{\text{data}}(\Vx,y)$，而不是使用大小固定的\gls{training_set}。
这种情况下，样本永远不会重复；每次更新的样本是从分布$p_\text{data}$中采样获得的无偏样本。
%  274 mid


在$\Vx$和$y$是离散时，以上的等价性很容易得到。
在这种情况下，\gls{generalization_error}（\eqnref{eq:8.2}）可以表示为
\begin{equation}
\label{eq:8.7}
    J^*(\Vtheta) = \sum_{\Vx} \sum_y p_{\text{data}}(\Vx, y) L(f(\Vx; \Vtheta),y),
\end{equation}
上式的准确梯度为
\begin{equation}
\label{eq:8.8}
    \Vg = \nabla_{\Vtheta} J^*(\Vtheta) = \sum_{\Vx} \sum_y p_{\text{data}}
    (\Vx, y) \nabla_{\Vtheta} L(f(\Vx;\Vtheta),y) .
\end{equation}
在\eqnref{eq:8.5}和\eqnref{eq:8.6}中，我们已经在对数似然中看到了相同的结果；现在我们发现这一点在包括似然的其他函数$L$上也是成立的。
在一些关于$p_\text{data}$和$L$的温和假设下，在$\Vx$和$y$是连续时也能得到类似的结果。
%  274 mid


因此，我们可以从\gls{DGD}~$p_\text{data}$抽取\gls{minibatch}样本$\{ \Vx^{(1)}, \dots,\Vx^{(m)} \}$以及对应的目标$y^{(i)}$，然后计算该\gls{minibatch}上损失函数关于对应参数的梯度
\begin{equation}
\label{eq:8.9}
    \hat{\Vg} = \frac{1}{m} \nabla_{\Vtheta} \sum_i L(f(\Vx^{(i)};\Vtheta),y^{(i)} ).
\end{equation}
以此获得\gls{generalization_error}准确梯度的\gls{unbiased}估计。
最后，在\gls{generalization_error}上使用\,\glssymbol{SGD}\,方法在方向$\hat{\Vg}$上更新$\Vtheta$。
%  274 end


当然，这个解释只能用于样本没有重复使用的情况。
然而，除非\gls{training_set}特别大，通常最好是多次遍历\gls{training_set}。
当多次遍历数据集更新时，只有第一遍满足\gls{generalization_error}梯度的\gls{unbiased}估计。
但是，额外的遍历更新当然会由于减小\gls{training_error}而得到足够的好处，以抵消其带来的\gls{training_error}和\gls{test_error}间差距的增加。
% -- 275 head


随着数据集的规模迅速增长，超越了计算能力的增速，
\gls{ML}应用每个样本只使用一次的情况变得越来越常见，甚至是不完整地使用\gls{training_set}。
在使用一个非常大的\gls{training_set}时，\gls{overfitting}不再是问题，而\gls{underfitting}和计算效率变成了主要的顾虑。
读者也可以参考~\cite{bottou-bousquet-2008}中关于训练样本数目增长时，\gls{generalization_error}上计算瓶颈影响的讨论。
% -- 275 mid


\section{\glsentrytext{NN}优化中的挑战}
\label{sec:challenges_in_neural_network_optimization}
优化通常是一个极其困难的任务。
传统的\gls{ML}会小心设计\gls{objective_function}和约束，以确保优化问题是凸的，
从而避免一般优化问题的复杂度。
在训练\gls{NN}时，我们肯定会遇到一般的\gls{nonconvex}情况。
即使是\gls{convex_optimization}，也并非没有任何问题。
在这一节中，我们会总结几个训练\gls{deep_model}时会涉及到的主要挑战。
% -- 275 mid


\subsection{\glsentrytext{ill_conditioning}}
\label{sec:ill_conditioning}
在优化凸函数时，会遇到一些挑战。
这其中最突出的是\,\gls{hessian}\,矩阵$\MH$的\gls{ill_conditioning}。
这是\gls{nume_optimization}、\gls{convex_optimization}或其他形式的优化中普遍存在的问题，更多细节请回顾\secref{sec:beyond_the_gradient_jacobian_and_hessian_matrices}。
% -- 275 mid

\gls{ill_conditioning}问题一般被认为存在于\gls{NN}训练过程中。
\gls{ill_conditioning}体现在\gls{SGD}会``卡''在某些情况，此时即使很小的更新步长也会增加\gls{cost_function}。
% -- 275 mid

回顾\eqnref{eq:4.9}，\gls{cost_function}的二阶\gls{taylor}级数展开预测\gls{GD}中的$-\epsilon\Vg$会增加
\begin{equation}
    \frac{1}{2} \epsilon^2 \Vg^\top \MH\Vg - \epsilon\Vg^\top\Vg
\end{equation}
到代价中。
当$\frac{1}{2} \epsilon^2 \Vg^\top\MH\Vg$超过$\epsilon\Vg^\top\Vg$时，梯度的\gls{ill_conditioning}会成为问题。
我们可以通过监测平方梯度范数$\Vg^\top\Vg$和$\Vg^\top \MH\Vg$，来判断\gls{ill_conditioning}是否不利于\gls{NN}训练任务。
在很多情况中，梯度范数不会在训练过程中显著缩小，但是$\Vg^\top\MH\Vg$的增长会超过一个数量级。
其结果是尽管梯度很强，学习会变得非常缓慢，因为\gls{learning_rate}必须收缩以弥补更强的\gls{curvature}。
如\figref{fig:chap8_grad_norm_increases}所示，成功训练的\gls{NN}中，梯度显著增加。
% -- 276 head

% -- 276 end
\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter8/figures/grad_norm_increases_color}}
\fi
\caption{\gls{GD}通常不会到达任何类型的\gls{critical_points}。
此示例中，在用于对象检测的\gls{convolutional_network}的整个训练期间， 梯度范数持续增加。
\emph{(左)}各个梯度计算的范数如何随时间分布的散点图。
为了方便作图，每\gls{epoch}仅绘制一个梯度范数。 
我们将所有梯度范数的移动平均绘制为实曲线。
梯度范数明显随时间增加，而不是如我们所期望的那样随训练过程收敛到\gls{critical_points}而减小。
\emph{(右)}尽管梯度递增，训练过程却相当成功。 
\gls{validation_set}上的分类误差可以降低到较低水平。
}
\label{fig:chap8_grad_norm_increases}
\end{figure}
% -- 276 end


% -- 276 mid
尽管\gls{ill_conditioning}还存在于除了\gls{NN}训练的其他情况中，有些适用于其他情况的解决\gls{ill_conditioning}的技术并不适用于\gls{NN}。
例如，\gls{newton_method}在解决带有\gls{poor_conditioning}的\,\gls{hessian}\,矩阵的\gls{convex_optimization}问题时，是一个非常优秀的工具，
但是我们将会在以下小节中说明\gls{newton_method}运用到\gls{NN}时需要很大的改动。


% -- 276 mid
\subsection{\glsentrytext{local_minima}}
\label{sec:local_minima}
\gls{convex_optimization}问题的一个突出特点是其可以简化为寻找一个\gls{local_minimum}的问题。
任何一个\gls{local_minimum}都是\gls{global_minimum}。
有些凸函数的底部是一个平坦的区域，而不是单一的\gls{global_minimum}，但该平坦区域中的任意点都是一个可以接受的解。
优化一个凸问题时，若发现了任何形式的\gls{critical_points}，我们都会知道已经找到了一个不错的可行解。
% -- 277 head


对于\gls{nonconvex}函数时，如\gls{NN}，有可能会存在多个\gls{local_minima}。
事实上，几乎所有的\gls{deep_model}基本上都会有非常多的\gls{local_minima}。
然而，我们会发现这并不是主要问题。
% -- 277 mid


由于\firstgls{model_identifiability}问题，\gls{NN}和任意具有多个等效参数化\gls{latent_variable}的模型都会具有多个\gls{local_minima}。
如果一个足够大的\gls{training_set}可以唯一确定一组模型参数，那么该模型被称为\gls{identifiable}。
带有\gls{latent_variable}的模型通常是不\gls{identifiable}，因为通过相互交换\gls{latent_variable}我们能得到等价的模型。
例如，考虑\gls{NN}的第一层，我们可以交换单元$i$和单元$j$的传入权重向量、传出权重向量而得到等价的模型。
如果\gls{NN}有$m$层，每层有$n$个单元，那么会有$n!^m$种排列\gls{hidden_unit}的方式。
这种不可辨认性被称为\firstgls{weight_space_symmetry}。
% -- 277 mid


除了\gls{weight_space_symmetry}，很多\gls{NN}还有其他导致不可辨认的原因。
例如，在任意\gls{rectified_linear}网络或者~\gls{maxout}~网络中，
我们可以将传入权重和\gls{bias_aff}放缩$\alpha$倍，然后将传出权重放缩$\frac{1}{\alpha}$倍，而保持模型等价。
这意味着，如果\gls{cost_function}不包括如\gls{weight_decay}这种直接依赖于权重而非模型输出的项，那么\gls{rectified_linear}网络或者~\gls{maxout}~网络的每一个\gls{local_minimum}都在等价的\gls{local_minima}的$(m\times n)$维双曲线上。
% -- 277 mid


这些\gls{model_identifiability}问题意味着\gls{NN}\gls{cost_function}具有非常多、甚至不可数无限多的\gls{local_minima}。
然而，所有这些由于不可辨识性问题而产生的\gls{local_minima}都有相同的\gls{cost_function}值。
因此，这些\gls{local_minima}并非是\gls{nonconvex}所带来的问题。
% -- 277 mid


如果\gls{local_minima}相比\gls{global_minimum}拥有很大的\gls{cost}，\gls{local_minima}会带来很大的隐患。
我们可以构建没有\gls{hidden_unit}的小规模\gls{NN}，其\gls{local_minima}的\gls{cost}比\gls{global_minimum}的\gls{cost}大很多~\citep{Sontag-cs89,Brady89,Gori-pami91}。
如果具有很大\gls{cost}的\gls{local_minima}是常见的，那么这将给基于梯度的优化算法带来极大的问题。
% -- 277 end


对于实际中感兴趣的网络，是否存在大量\gls{cost}很高的\gls{local_minima}，优化算法是否会碰到这些\gls{local_minima}，都是尚未解决的公开问题。
多年来，大多数从业者认为\gls{local_minima}是困扰\gls{NN}优化的常见问题。
如今，情况有所变化。
这个问题仍然是学术界的热点问题，但是学者们现在猜想，对于足够大的\gls{NN}而言，
大部分\gls{local_minima}都具有很小的\gls{cost_function}，我们能不能找到真正的\gls{global_minimum}并不重要，而是需要在参数空间中找到一个\gls{cost}很小（但不是最小）的点~\citep{Saxe-et-al-ICLR13,Dauphin-et-al-NIPS2014-small,GoodfellowOptimization15,Choromanska-et-al-AISTATS2015}。
% 278 head

很多从业者将\gls{NN}优化中的所有困难都归结于\gls{local_minima}。
我们鼓励从业者要仔细分析特定的问题。
一种能够排除\gls{local_minima}是主要问题的检测方法是画出梯度范数随时间的变化。
如果梯度范数没有缩小到一个微小的值，那么该问题既不是\gls{local_minima}，也不是其他形式的\gls{critical_points}。
%这种消极的测试可以排除局部极小值是造成问题的原因。
在高维空间中，很难明确证明\gls{local_minima}是导致问题的原因。
许多并非\gls{local_minima}的结构也具有很小的梯度。
% 278 mid

\subsection{高原、\glsentrytext{saddle_points}和其他平坦区域}
\label{sec:plateaus_saddle_points_and_other_flat_regions}
对于很多高维\gls{nonconvex}函数而言，\gls{local_minima}（以及\gls{maxima}）事实上都远少于另一类梯度为零的点：\gls{saddle_points}。
\gls{saddle_points}附近的某些点比\gls{saddle_points}有更大的\gls{cost}，而其他点则有更小的\gls{cost}。
在\gls{saddle_points}处，\gls{hessian}\,矩阵同时具有正负特征值。
位于正特征值对应的特征向量方向的点比\gls{saddle_points}有更大的\gls{cost}，反之，位于负特征值对应的特征向量方向的点有更小的\gls{cost}。
我们可以将\gls{saddle_points}视为\gls{cost_function}某个横截面上的\gls{local_minimum}，同时也可以视为\gls{cost_function}某个横截面上的\gls{local_maximum}。
\figref{fig:chap4_saddle_3d_color}\,给了一个示例。
% 278 mid


多类随机函数表现出以下性质：低维空间中，\gls{local_minima}很普遍。
在更高维空间中，\gls{local_minima}很罕见，而\gls{saddle_points}则很常见。
对于这类函数$f:\SetR^n \to \SetR$而言，\gls{saddle_points}和\gls{local_minima}的数目比率的期望随$n$指数级增长。
我们可以从直觉上理解这种现象——\gls{hessian}\,矩阵在\gls{local_minimum}处只有正特征值。
而在\gls{saddle_points}处，\gls{hessian}\,矩阵则同时具有正负特征值。
试想一下，每个特征值的正负号由抛硬币决定。
在一维情况下，很容易抛硬币得到正面朝上一次而获取\gls{local_minimum}。
在$n$-维空间中，要抛掷$n$次硬币都正面朝上的难度是指数级的。 
具体可以参考~\cite{Dauphin-et-al-NIPS2014-small}，它回顾了相关的理论工作。
% -- 278 end


很多随机函数一个惊人性质是，当我们到达\gls{cost}较低的区间时，\gls{hessian}\,矩阵的特征值为正的可能性更大。
和抛硬币类比，这意味着如果我们处于低\gls{cost}的\gls{critical_points}时，抛掷硬币正面朝上$n$次的概率更大。
这也意味着，\gls{local_minima}具有低\gls{cost}的可能性比高\gls{cost}要大得多。
具有高\gls{cost}的\gls{critical_points}更有可能是\gls{saddle_points}。
具有极高\gls{cost}的\gls{critical_points}就很可能是\gls{local_maxima}了。
% -- 279 head


以上现象出现在许多种类的随机函数中。
那么是否在\gls{NN}中也有发生呢？
\cite{Baldi89}从理论上证明，不具非线性的浅层\gls{AE}（\chapref{chap:autoencoders}中将介绍的一种将输出训练为输入拷贝的\gls{feedforward_network}）只有\gls{global_minima}和\gls{saddle_points}，没有\gls{cost}比\gls{global_minima}更大的\gls{local_minima}。
他们还发现这些结果能够扩展到不具非线性的更深的网络上，不过没有证明。
这类网络的输出是其输入的线性函数，但它们仍然有助于分析非线性\gls{NN}模型，因为它们的\gls{loss_function}是关于参数的\gls{nonconvex}函数。
这类网络本质上是多个矩阵组合在一起。
\cite{Saxe-et-al-ICLR13}精确解析了这类网络中完整的学习动态，表明这些模型的学习能够捕捉到许多在训练具有非线性\gls{activation_function}的\gls{deep_model}时观察到的定性特征。
\cite{Dauphin-et-al-NIPS2014-small}通过实验表明，真实的\gls{NN}也存在包含很多高\gls{cost}\gls{saddle_points}的\gls{loss_function}。
\cite{Choromanska-et-al-AISTATS2015}提供了额外的理论论点，表明另一类和\gls{NN}相关的高维随机函数也满足这种情况。

% -- 279 mid

\gls{saddle_points}激增对于训练算法来说有哪些影响呢？
对于只使用梯度信息的一阶优化算法而言，目前情况还不清楚。
\gls{saddle_points}附近的梯度通常会非常小。
另一方面，实验中\gls{GD}似乎可以在许多情况下逃离\gls{saddle_points}。
\cite{GoodfellowOptimization15}可视化了最新\gls{NN}的几个学习轨迹，\figref{fig:chap8_plot_atmu_relu_5}\,给了一个例子。
这些可视化显示，在突出的\gls{saddle_points}附近，\gls{cost_function}都是平坦的，权重都为零。
但是他们也展示了\gls{GD}轨迹能够迅速逸出该区间。
\cite{GoodfellowOptimization15}也主张，应该可以通过分析来表明连续时间的\gls{GD}会逃离而不是吸引到\gls{saddle_points}，但对\gls{GD}更现实的使用场景来说，情况或许会有所不同。

% -- 279 mid

% 280 head

\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter8/figures/plot_atmu_relu_5}}
\fi
\caption{\gls{NN}\gls{cost_function}的可视化。
这些可视化对应用于真实\gls{object_recognition}和\gls{NLP}任务的\gls{feedforward_neural_network}、\gls{convolutional_network}和\gls{recurrent_network}而言是类似的。
令人惊讶的是，这些可视化通常不会显示出很多明显的障碍。
大约2012年，在\gls{SGD}开始成功训练非常大的模型之前，相比这些投影所显示的\gls{NN}\gls{cost_function}的表面通常被认为有更多的\gls{nonconvex}结构。
该投影所显示的主要障碍是初始参数附近的高\gls{cost}\gls{saddle_points}，但如由蓝色路径所示，\glssymbol{SGD}\,训练轨迹能轻易地逃脱该鞍点。
大多数训练时间花费在横穿\gls{cost_function}中相对平坦的峡谷，可能由于梯度中的高噪声、或该区域中~\gls{hessian}~矩阵的\gls{poor_conditioning}，或者需要经过间接的弧路径绕过图中可见的高``山'' 。
图经~\citet{GoodfellowOptimization15}许可改编。
}
\label{fig:chap8_plot_atmu_relu_5}
\end{figure}
% 280 head


% -- 279 end
对于\gls{newton_method}而言，\gls{saddle_points}显然是一个问题。
\gls{GD}旨在朝``下坡''移动，而非明确寻求\gls{critical_points}。
而\gls{newton_method}的目标是寻求梯度为零的点。
如果没有适当的修改，\gls{newton_method}就会跳进一个\gls{saddle_points}。
高维空间中\gls{saddle_points}的激增或许解释了在\gls{NN}训练中为什么\gls{second_order_method}无法成功取代\gls{GD}。
\cite{Dauphin-et-al-NIPS2014-small}介绍了二阶优化的\firstgls{saddle_free_newton_method}，并表明和传统算法相比有显著改进。
\gls{second_order_method}仍然难以扩展到大型\gls{NN}，但是如果这类无鞍算法能够扩展的话，还是很有希望的。
% -- 280 mid


除了\gls{minima}和\gls{saddle_points}，还存在其他梯度为零的点。
例如从优化的角度看与\gls{saddle_points}很相似的\gls{maxima}，很多算法不会被吸引到\gls{maxima}，除了未经修改的\gls{newton_method}。
和\gls{minima}一样，许多种类的随机函数的\gls{maxima}在高维空间中也是指数级稀少。
% -- 280 mid


也可能存在恒值的、宽且平坦的区域。
在这些区域，梯度和\,\gls{hessian}\,矩阵都是零。
这种退化的情形是所有\gls{nume_optimization}算法的主要问题。
在凸问题中，一个宽而平坦的区间肯定包含\gls{global_minima}，但是对于一般的优化问题而言，
这样的区域可能会对应着\gls{objective_function}中一个较高的值。
% -- 280 end


\subsection{悬崖和\glsentrytext{explode_gradient}}
\label{sec:cliffs_and_exploding_gradients}
% 281 head
多层\gls{NN}通常存在像悬崖一样的斜率较大区域，如\figref{fig:chap8_cliff}所示。
这是由于几个较大的权重相乘导致的。
遇到斜率极大的悬崖结构时，梯度更新会很大程度地改变参数值，通常会完全跳过这类悬崖结构。
% 281 head


% 281 end
\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter8/figures/cliff_color}}
\fi
\caption{高度非线性的\gls{DNN}或\gls{RNN}的\gls{objective_function}通常包含由几个参数连乘而导致的参数空间中尖锐非线性。
这些非线性在某些区域会产生非常大的导数。
当参数接近这样的悬崖区域时，\gls{GD}更新可以使参数弹射得非常远，可能会使大量已完成的优化工作成为无用功。
图经 \citet{Pascanu+al-ICML2013-small}许可改编。}
\label{fig:chap8_cliff}
\end{figure}
% 281 end


不管我们是从上还是从下接近悬崖，情况都很糟糕，但幸运的是我们可以用使用\secref{sec:clipping_gradients}介绍的启发式\firstgls{gradient_clipping}来避免其严重的后果。
其基本想法源自梯度并没有指明最佳步长，只说明了在无限小区域内的最佳方向。
当传统的\gls{GD}算法提议更新很大一步时，启发式\gls{gradient_clipping}会干涉来减小步长，从而使其不太可能走出梯度近似为\gls{steepest}方向的悬崖区域。
悬崖结构在\gls{RNN}的\gls{cost_function}中很常见，因为这类模型会涉及到多个因子的相乘，其中每个因子对应一个\gls{time_step}。
因此，长期时间序列会产生大量相乘。
% 281 mid


% 281 end
\subsection{\glsentrytext{long_term_dependency}}
\label{sec:long_term_dependencies}
当\gls{computational_graph}变得极深时，\gls{NN}优化算法会面临的另外一个难题就是\gls{long_term_dependency}问题——由于变深的结构使模型丧失了学习到先前信息的能力，让优化变得极其困难。 
深层的\gls{computational_graph}不仅存在于\gls{feedforward_network}，还存在于之后介绍的\gls{recurrent_network}中（在\chapref{chap:sequence_modeling_recurrent_and_recursive_nets}中描述）。
因为\gls{recurrent_network}要在很长时间序列的各个时刻重复应用相同操作来构建非常深的计算图，并且模型参数共享，这使问题更加凸显。

% 282 head

例如，假设某个\gls{computational_graph}中包含一条反复与矩阵$\MW$相乘的路径。
那么$t$步后，相当于乘以$\MW^t$。
假设$\MW$有特征值分解$\MW = \MV \text{diag}(\Vlambda) \MV^{-1}$。
在这种简单的情况下，很容易看出
\begin{equation}
  \MW^t = (\MV \text{diag}(\Vlambda) \MV^{-1})^t = \MV\text{diag}(\Vlambda)^t  \MV^{-1}.
\end{equation}
当特征值$\lambda_i$不在$1$附近时，若在量级上大于$1$则会爆炸；若小于$1$时则会消失。
\firstgls{vanish_explode_gradient}是指该\gls{computational_graph}上的梯度也会因为$\text{diag}(\Vlambda)^t$大幅度变化。
\gls{vanish_gradient}使得我们难以知道参数朝哪个方向移动能够改进\gls{cost_function}，而\gls{explode_gradient}会使得学习不稳定。
之前描述的促使我们使用\gls{gradient_clipping}的悬崖结构便是\gls{explode_gradient}现象的一个例子。

% 282 mid

此处描述的在各\gls{time_step}重复与$\MW$相乘非常类似于寻求矩阵$\MW$的最大特征值及对应特征向量的\firstgls{power_method}。
从这个观点来看，$\Vx^\top\MW^t$最终会丢弃$\Vx$中所有与$\MW$的主特征向量正交的成分。

% 282 mid

\gls{recurrent_network}在各\gls{time_step}上使用相同的矩阵$\MW$，而\gls{feedforward_network}并没有。
所以即使使用非常深层的\gls{feedforward_network}，也能很大程度上有效地避免\gls{vanish_explode_gradient}~\citep{Sussillo14}。

% 282 mid

在更详细地描述\gls{recurrent_network}之后，我们将会在\secref{sec:the_challenge_of_long_term_dependencies}进一步讨论\gls{recurrent_network}训练中的挑战。

% 282 mid

\subsection{非精确梯度}
\label{sec:inexact_gradients}
大多数优化算法的先决条件都是我们知道精确的梯度或是\,\gls{hessian}\,矩阵。
在实践中，通常这些量会有\gls{noise}，甚至是\gls{biased}的估计。
几乎每一个\gls{DL}算法都需要基于采样的估计，至少使用训练样本的\gls{minibatch}来计算梯度。

% 282 end

在其他情况，我们希望最小化的\gls{objective_function}实际上是难以处理的。
当\gls{objective_function}不可解时，通常其梯度也是难以处理的。
在这种情况下，我们只能近似梯度。
这些问题主要出现在第三部分中更高级的模型中。
例如，\gls{contrastive_divergence}是用来近似\gls{BM}中难以处理的对数似然梯度的一种技术。

% 283 head

各种\gls{NN}优化算法的设计都考虑到了梯度估计的缺陷。
我们可以选择比真实\gls{loss_function}更容易估计的\gls{surrogate_loss_function}来避免这个问题。

% 283 mid

\subsection{局部和全局结构间的弱对应}
\label{sec:poor_correspondence_between_local_and_global_structure}
迄今为止，我们讨论的许多问题都是关于\gls{loss_function}在单个点的性质——若$J(\Vtheta)$是当前点$\Vtheta$的\gls{poor_conditioning}，或者$\Vtheta$在悬崖中，或者$\Vtheta$是一个下降方向不明显的\gls{saddle_points}，那么会很难更新当前步。

% 283 mid

如果该方向在局部改进很大，但并没有指向\gls{cost}低得多的遥远区域，那么我们有可能在单点处克服以上所有困难，但仍然表现不佳。

% 283 mid

\cite{GoodfellowOptimization15}认为大部分训练的运行时间取决于到达解决方案的轨迹长度。 
如\figref{fig:chap8_plot_atmu_relu_5}所示，学习轨迹将花费大量的时间探寻一个围绕山形结构的宽弧。

% 283 mid

大多数优化研究的难点集中于训练是否找到了\gls{global_minimum}、\gls{local_minimum}或是\gls{saddle_points}，但在实践中\gls{NN}不会到达任何一种\gls{critical_points}。
\figref{fig:chap8_grad_norm_increases}表明\gls{NN}通常不会到达梯度很小的区域。
甚至，这些\gls{critical_points}不一定存在。
例如，\gls{loss_function} $-\log p(y\mid\Vx;\Vtheta)$ 可以没有\gls{global_minimum}，而是当随着训练模型逐渐稳定后，渐近地收敛于某个值。    
对于具有离散的$y$和~\ENNAME{softmax}~分布$p(y\mid\Vx)$的分类器而言，若模型能够正确分类\gls{training_set}上的每个样本，则负对数似然可以无限趋近但不会等于零。
同样地，实值模型$p(y\mid\Vx) = \mathcal{N}(y;f(\Vtheta),\beta^{-1})$的负对数似然会趋向于负无穷——如果$f(\Vtheta)$能够正确预测所有\gls{training_set}中的目标$y$，学习算法会无限制地增加$\beta$。
\figref{fig:chap8_bad_global}给出了一个失败的例子，即使没有\gls{local_minima}和\gls{saddle_points}，该例还是不能从局部优化中找到一个良好的\gls{cost_function}值。

% 283 end

% 284 head

\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter8/figures/bad_global_color}}
\fi
\caption{如果局部表面没有指向全局解，基于局部下坡移动的优化可能就会失败。
这里我们提供一个例子，说明即使在没有\gls{saddle_points}或\gls{local_minima}的情况下，优化过程会如何失败。
此例中的\gls{cost_function}仅包含朝向低值而不是\gls{minima}的渐近线。
在这种情况下，造成这种困难的主要原因是初始化在``山''的错误一侧，并且无法遍历。
在高维空间中，学习算法通常可以环绕过这样的高山，但是相关的轨迹可能会很长，并且导致过长的训练时间，如\figref{fig:chap8_plot_atmu_relu_5}所示。
}
\label{fig:chap8_bad_global}
\end{figure}

% 284 head

未来的研究需要进一步探索影响学习轨迹长度和更好地表征训练过程的结果。

% 284 mid

许多现有研究方法在求解具有困难全局结构的问题时，旨在寻求良好的初始点，而不是开发非局部范围更新的算法。

% 284 mid

\gls{GD}和基本上所有的可以有效训练\gls{NN}的学习算法，都是基于局部较小更新。
之前的小节主要集中于为何这些局部范围更新的正确方向难以计算。
我们也许能计算\gls{objective_function}的一些性质，如近似的有偏梯度或正确方向估计的方差。
在这些情况下，难以确定局部下降能否定义通向有效解的足够短的路径，但我们并不能真的遵循局部下降的路径。
\gls{objective_function}可能有诸如\gls{poor_conditioning}或不连续梯度的问题，使得梯度为\gls{objective_function}提供较好近似的区间非常小。
在这些情况下，步长为$\epsilon$的局部下降可能定义了到达解的合理的短路经，但是我们只能计算步长为$\delta \ll \epsilon$的局部下降方向。
在这些情况下，局部下降或许能定义通向解的路径，但是该路径包含很多次更新，因此遵循该路径会带来很高的计算代价。
有时，比如说当\gls{objective_function}有一个宽而平的区域，或是我们试图寻求精确的\gls{critical_points}（通常来说后一种情况只发生于显式求解\gls{critical_points}的方法，如\gls{newton_method}）时，局部信息不能为我们提供任何指导。
在这些情况下，\gls{local_descent}完全无法定义通向解的路径。
在其他情况下，局部移动可能太过贪心，朝着下坡方向移动，却和所有可行解南辕北辙，如\figref{fig:chap8_bad_global}所示，或者是用舍近求远的方法来求解问题，如\figref{fig:chap8_plot_atmu_relu_5}所示。
目前，我们还不了解这些问题中的哪一个与\gls{NN}优化中的难点最相关，这是研究领域的热点方向。

% 285 head

不管哪个问题最重要，如果存在一个区域，我们遵循\gls{local_descent}便能合理地直接到达某个解，并且我们能够在该良好区域上初始化学习，那么这些问题都可以避免。
最终的观点还是建议在传统优化算法上研究怎样选择更佳的初始化点，以此来实现目标更切实可行。

% 285 mid

\subsection{优化的理论限制}
\label{sec:theoretical_limits_of_optimization}
一些理论结果表明，我们为\gls{NN}设计的任何优化算法都有性能限制\citep{Blum92,JuddBook,wolpert96no}。
通常这些结果不影响\gls{NN}在实践中的应用。

% 285 mid

一些理论结果仅适用于\gls{NN}的单元输出离散值的情况。
然而，大多数\gls{NN}单元输出光滑的连续值，使得局部搜索求解优化可行。
一些理论结果表明，存在某类问题是不可解的，但很难判断一个特定问题是否属于该类。
其他结果表明，寻找给定规模的网络的一个可行解是很困难的，
但在实际情况中，我们通过设置更多参数，使用更大的网络，能轻松找到可接受的解。
此外，在\gls{NN}训练中，我们通常不关注某个函数的精确\gls{minimum}，而只关注将其值下降到足够小以获得一个良好的\gls{generalization_error}。
对优化算法是否能完成此目标进行理论分析是非常困难的。
因此，研究优化算法更现实的性能上界仍然是学术界的一个重要目标。

% 285 end

% 286 head

\section{基本算法}
\label{sec:basic_algorithms}
之前我们已经介绍了\gls{GD}（\secref{sec:gradient_based_optimization}），即沿着整个\gls{training_set}的梯度方向下降。
这可以使用\gls{SGD}很大程度地加速，沿着随机挑选的\gls{minibatch}数据的梯度下降方向，就像\secref{sec:stochastic_gradient_descent_chap5}和\secref{sec:batch_and_minibatch_algorithms}中讨论的一样。

% 286 head

\subsection{\glsentrytext{SGD}}
\label{sec:stochastic_gradient_descent_chap8}
\glsacr{SGD}及其变种很可能是一般\gls{ML}中应用最多的优化算法，特别是在\gls{DL}中。
如\secref{sec:batch_and_minibatch_algorithms}中所讨论的，按照\gls{DGD}抽取$m$个\gls{minibatch}（独立同分布的）样本，通过计算它们梯度均值，我们可以得到梯度的\gls{unbiased}估计。

% 286 mid

\algref{alg:sgd}展示了如何沿着这个梯度的估计下降。

% 286 mid

% 286 end

\begin{algorithm}[ht]
\caption{\gls{SGD}（\glssymbol{SGD}）在第$k$个训练迭代的更新}
\label{alg:sgd}
\begin{algorithmic}
\REQUIRE \gls{learning_rate} $\epsilon_k$
\REQUIRE 初始参数$\Vtheta$
\WHILE{停止\gls{criterion}未满足}
    \STATE 从\gls{training_set}中采包含$m$个样本$\{ \Vx^{(1)},\dots, \Vx^{(m)}\}$ 的\gls{minibatch}，其中$\Vx^{(i)}$对应目标为$\Vy^{(i)}$。
    \STATE 计算梯度估计： $\hat{\Vg} \leftarrow + 
         \frac{1}{m} \nabla_{\Vtheta} \sum_i L(f(\Vx^{(i)};\Vtheta),\Vy^{(i)})$
    \STATE 应用更新：$\Vtheta \leftarrow \Vtheta - \epsilon \hat{\Vg}$
\ENDWHILE
\end{algorithmic}
\end{algorithm}

% 286 end

% 286 mid

\glssymbol{SGD}\,算法中的一个关键参数是\gls{learning_rate}。
之前，我们介绍的\,\glssymbol{SGD}\,使用固定的\gls{learning_rate}。
在实践中，有必要随着时间的推移逐渐降低\gls{learning_rate}，因此我们将第$k$步迭代的\gls{learning_rate}记作$\epsilon_k$。

% 286 mid

这是因为\,\glssymbol{SGD}\,中梯度估计引入的噪声源（$m$个训练样本的随机采样）并不会在\gls{minimum}处消失。
相比之下，当我们使用\gls{batch}\gls{GD}到达\gls{minimum}时，整个\gls{cost_function}的真实梯度会变得很小，之后为$\mathbf{0}$，因此\gls{batch}\gls{GD}可以使用固定的\gls{learning_rate}。
保证\,\glssymbol{SGD}\,收敛的一个充分条件是
\begin{equation}
\label{eq:8.12}
    \sum_{k=1}^\infty \epsilon_k = \infty,
\end{equation}
且
\begin{equation}
\label{eq:8.13}
    \sum_{k=1}^\infty \epsilon_k^2 < \infty.
\end{equation}

% 287 head

实践中，一般会线性衰减\gls{learning_rate}直到第$\tau$次迭代：
\begin{equation}
\label{eq:8.14}
    \epsilon_k = (1-\alpha) \epsilon_0 + \alpha \epsilon_\tau
\end{equation}
其中$\alpha = \frac{k}{\tau}$。
在$\tau$步迭代之后，一般使$\epsilon$保持常数。

% 287 mid

\gls{learning_rate}可通过试验和误差来选取，通常最好的选择方法是监测\gls{objective_function}值随时间变化的学习曲线。
与其说是科学，这更像是一门艺术，我们应该谨慎地参考关于这个问题的大部分指导。
使用线性策略时，需要选择的参数为$\epsilon_0$，$\epsilon_\tau$，$\tau$。  
通常$\tau$被设为需要反复遍历\gls{training_set}几百次的迭代次数。
通常$\epsilon_\tau$应设为大约$\epsilon_0$的$1\%$。
主要问题是如何设置$\epsilon_0$。
若$\epsilon_0$太大，学习曲线将会剧烈振荡，\gls{cost_function}值通常会明显增加。
温和的振荡是良好的，容易在训练随机\gls{cost_function}（例如使用\,\gls{dropout}\,的\gls{cost_function}）时出现。
如果\gls{learning_rate}太小，那么学习过程会很缓慢。
如果初始\gls{learning_rate}太低，那么学习可能会卡在一个相当高的\gls{cost}值。
通常，就总训练时间和最终\gls{cost}值而言，最优初始\gls{learning_rate}会高于大约迭代$100$次左右后达到最佳效果的\gls{learning_rate}。
因此，通常最好是检测最早的几轮迭代，选择一个比在效果上表现最佳的\gls{learning_rate}更大的\gls{learning_rate}，但又不能太大导致严重的震荡。  

% 287 mid

\glssymbol{SGD}\,及相关的\gls{minibatch}亦或更广义的基于梯度优化的在线学习算法，一个重要的性质是每一步更新的计算时间不依赖训练样本数目的多寡。
即使训练样本数目非常大时，它们也能收敛。
对于足够大的数据集，\glssymbol{SGD}\,可能会在处理整个\gls{training_set}之前就收敛到最终\gls{test_set}误差的某个固定容差范围内。

% 287 mid

% 287 end

研究优化算法的收敛率，一般会衡量\firstgls{excess_error} $J(\Vtheta) - \min_{\Vtheta} J(\Vtheta)$，即当前\gls{cost_function}超出最低可能\gls{cost}的量。
\glssymbol{SGD}\,应用于凸问题时，$k$步迭代后的\gls{excess_error}量级是$O(\frac{1}{\sqrt{k}})$，在强凸情况下是$O(\frac{1}{k})$。
除非假定额外的条件，否则这些界限不能进一步改进。
\gls{batch}\gls{GD}在理论上比\gls{SGD}有更好的收敛率。
然而，Cram\'er-Rao界限~\citep{Cramer-1946,Rao-1945}指出，\gls{generalization_error}的下降速度不会快于$O(\frac{1}{k})$。
\cite{bottou-bousquet-2008-small}因此认为对于\gls{ML}任务，不值得探寻收敛快于$O(\frac{1}{k})$的优化算法——更快的收敛可能对应着\gls{overfitting}。
此外，渐近分析掩盖了\gls{SGD}在少量更新步之后的很多优点。
对于大数据集，\glssymbol{SGD}\,只需非常少量样本计算梯度从而实现初始快速更新，远远超过了其缓慢的渐近收敛。
本章剩余部分介绍的大多数算法在实践中都受益于这种性质，但是损失了常数倍$O(\frac{1}{k})$的渐近分析。
我们也可以在学习过程中逐渐增大\gls{minibatch}的大小，以此权衡\gls{batch}\gls{GD}和\gls{SGD}两者的优点。

% 288 mid

了解\,\glssymbol{SGD}\,更多的信息，请查看~\cite{Bottou98}。

% 288 mid

\subsection{\glsentrytext{momentum}}
\label{sec:momentum}
虽然\gls{SGD}仍然是非常受欢迎的优化方法，但其学习过程有时会很慢。
\gls{momentum}方法~\citep{polyak1964some}旨在加速学习，特别是处理高\gls{curvature}、小但一致的梯度，或是带\gls{noise}的梯度。
\gls{momentum}算法积累了之前梯度指数级衰减的移动平均，并且继续沿该方向移动。
\gls{momentum}的效果如\figref{fig:chap8_momentum}所示。

% 288 mid

% 289 head

\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter8/figures/momentum_color}}
\fi
\caption{\gls{momentum}的主要目的是解决两个问题：\gls{hessian}\,矩阵的\gls{poor_conditioning}和随机梯度的方差。 
我们通过此图说明\gls{momentum}如何克服这两个问题的第一个。
等高线描绘了一个二次\gls{loss_function}（具有\gls{poor_conditioning}的\,\gls{hessian}\,矩阵）。
横跨轮廓的红色路径表示\gls{momentum}学习规则所遵循的路径，它使该函数最小化。
我们在该路径的每个步骤画一个箭头，表示\gls{GD}将在该点采取的步骤。
我们可以看到，一个\gls{poor_conditioning}的二次\gls{objective_function}看起来像一个长而窄的山谷或具有陡峭边的峡谷。
\gls{momentum}正确地纵向穿过峡谷，而普通的梯度步骤则会浪费时间在峡谷的窄轴上来回移动。
比较\figref{fig:chap4_poor_conditioning_color}，它也显示了没有\gls{momentum}的\gls{GD}的行为。
}
\label{fig:chap8_momentum}
\end{figure}

% 289 head

从形式上看，\gls{momentum}算法引入了变量$\Vv$充当速度角色——它代表参数在参数空间移动的方向和速率。
速度被设为负梯度的指数衰减平均。
名称\firstgls{momentum}来自物理类比，根据牛顿运动定律，负梯度是移动参数空间中粒子的力。
\gls{momentum}在物理学上定义为质量乘以速度。
在\gls{momentum}学习算法中，我们假设是单位质量，因此速度向量$\Vv$也可以看作是粒子的\gls{momentum}。
\gls{hyperparameter}$\alpha\in[0,1)$决定了之前梯度的贡献衰减得有多快。
更新规则如下：
\begin{align}
\Vv & \leftarrow \alpha \Vv - \epsilon \nabla_{\Vtheta} \left( \frac{1}{m} \sum_{i=1}^m  L(\Vf(\Vx^{(i)}; \Vtheta), \Vy^{(i)}   )  \right), \\
\Vtheta & \leftarrow \Vtheta  + \Vv .
\end{align}
速度$\Vv$累积了梯度元素$\nabla_{\Vtheta}( \frac{1}{m} \sum_{i=1}^m L( \Vf(\Vx^{(i)}; \Vtheta), \Vy^{(i)} )  )$。
相对于$\epsilon$，$\alpha$越大，之前梯度对现在方向的影响也越大。
带\gls{momentum}的\,\glssymbol{SGD}\,算法如\algref{alg:momentum}所示。

% 289 end

% 289 mid

\begin{algorithm}[ht]
\caption{使用\gls{momentum}的\gls{SGD}（\glssymbol{SGD}）}
\label{alg:momentum}
\begin{algorithmic}
\REQUIRE \gls{learning_rate} $\epsilon$， \gls{momentum}参数 $\alpha$
\REQUIRE 初始参数 $\Vtheta$，初始速度 $\Vv$
\WHILE{没有达到停止\gls{criterion}}
    \STATE 从\gls{training_set}中采包含$m$个样本$\{ \Vx^{(1)},\dots, \Vx^{(m)}\}$ 的\gls{minibatch}，对应目标为$\Vy^{(i)}$。
    \STATE 计算梯度估计：$\Vg \leftarrow 
         \frac{1}{m} \nabla_{\Vtheta} \sum_i L(f(\Vx^{(i)};\Vtheta),\Vy^{(i)})$
    \STATE  计算速度更新：$\Vv \leftarrow \alpha \Vv - 
    \epsilon \Vg$
    \STATE 应用更新：$\Vtheta \leftarrow \Vtheta + \Vv$ 
\ENDWHILE
\end{algorithmic}
\end{algorithm}

% 289 mid

% 289 end

之前，步长只是梯度范数乘以\gls{learning_rate}。
现在，步长取决于梯度\emph{序列}的大小和排列。
当许多连续的梯度指向相同的方向时，步长最大。
如果\gls{momentum}算法总是观测到梯度$\Vg$，那么它会在方向$-g$上不停加速，直到达到最终速度，其中步长大小为
\begin{equation}
    \frac{\epsilon \norm{\Vg}}{1-\alpha} .
\end{equation}
因此将\gls{momentum}的\gls{hyperparameter}视为$\frac{1}{1-\alpha}$有助于理解。
例如，$\alpha=0.9$对应着最大速度$10$倍于\gls{GD}算法。

% 290 head

在实践中，$\alpha$的一般取值为$0.5$，$0.9$和$0.99$。
和\gls{learning_rate}一样，$\alpha$也会随着时间不断调整。 
一般初始值是一个较小的值，随后会慢慢变大。
随着时间推移调整$\alpha$没有收缩$\epsilon$重要。

% 290 mid

我们可以将\gls{momentum}算法视为模拟连续时间下牛顿动力学下的粒子。
这种物理类比有助于直觉上理解\gls{momentum}和\gls{GD}算法是如何表现的。

% 290 mid

粒子在任意时间点的位置由$\Vtheta(t)$给定。
粒子会受到净力$\Vf(t)$。
该力会导致粒子加速：
\begin{equation}
    \Vf(t) = \frac{\partial^2}{\partial t^2} \Vtheta(t) .
\end{equation}
与其将其视为位置的二阶\gls{differential_equation}，我们不如引入表示粒子在时间$t$处速度的变量$\Vv(t)$，将牛顿动力学重写为一阶\gls{differential_equation}：
\begin{align}
    \Vv(t) &= \frac{\partial}{\partial t} \Vtheta(t) , \\
    \Vf(t) &= \frac{\partial}{\partial t} \Vv(t) .
\end{align}
由此，\gls{momentum}算法包括通过数值模拟求解\gls{differential_equation}。
求解\gls{differential_equation}的一个简单数值方法是欧拉方法，通过在每个梯度方向上小且有限的步来简单模拟该等式定义的动力学。
% 290 mid


这解释了\gls{momentum}更新的基本形式，但具体什么是力呢？
一个力正比于\gls{cost_function}的负梯度$-\nabla_{\Vtheta} J(\Vtheta)$。
该力推动粒子沿着\gls{cost_function}表面下坡的方向移动。
\gls{GD}算法基于每个梯度简单地更新一步，而使用\gls{momentum}算法的牛顿方案则使用该力改变粒子的速度。
我们可以将粒子视作在冰面上滑行的冰球。
每当它沿着表面最陡的部分下降时，它会沿该方向加速滑行，直到开始向上滑动为止。
% 291 head


另一个力也是必要的。
如果\gls{cost_function}的梯度是唯一的力，那么粒子可能永远不会停下来。
想象一下，假设理想情况下冰面没有摩擦，一个冰球从山谷的一端下滑，上升到另一端，永远来回振荡。
要解决这个问题，我们添加另一个正比于$-\Vv(t)$的力。
在物理术语中，此力对应于粘性阻力，就像粒子必须通过一个抵抗介质，如糖浆。
这会导致粒子随着时间推移逐渐失去能量，最终收敛到\gls{local_minimum}。
% 291 mid


为什么要特别使用$-\Vv(t)$和粘性阻力呢？
部分原因是因为$-\Vv(t)$在数学上的便利——速度的整数幂很容易处理。
然而，其他物理系统具有基于速度的其他整数幂的其他类型的阻力。
例如，颗粒通过空气时会受到正比于速度平方的湍流阻力，而颗粒沿着地面移动时会受到恒定大小的摩擦力。
这些选择都不合适。
湍流阻力，正比于速度的平方，在速度很小时会很弱。
不够强到使粒子停下来。
非零值初始速度的粒子仅受到湍流阻力，会从初始位置永远地移动下去，和初始位置的距离大概正比于$O(\log t)$。
因此我们必须使用速度较低幂次的力。
如果幂次为零，相当于干摩擦，那么力太强了。
当\gls{cost_function}的梯度表示的力很小但非零时，由于摩擦导致的恒力会使得粒子在达到\gls{local_minimum}之前就停下来。
粘性阻力避免了这两个问题——它足够弱，可以使梯度引起的运动直到达到最小，但又足够强，使得坡度不够时可以阻止运动。
% 291 end


\subsection{\glsentrytext{nmomentum}}
\label{sec:nesterov_momentum}
受Nesterov加速梯度算法\citep{Nesterov83b,Nesterov03}启发，\cite{sutskeverimportance}提出了\gls{momentum}算法的一个变种。
这种情况的更新规则如下：
\begin{align}
    \Vv &\leftarrow \alpha\Vv - \epsilon \nabla_{\Vtheta} \left[
    \frac{1}{m} \sum_{i=1}^m L\big( \Vf(\Vx^{(i)}; \Vtheta + \alpha \Vv), \Vy^{(i)} \big)
 \right], \\
    \Vtheta &\leftarrow \Vtheta + \Vv ,
\end{align}
其中参数$\alpha$和$\epsilon$发挥了和标准\gls{momentum}方法中类似的作用。 
\gls{nmomentum}和标准\gls{momentum}之间的区别体现在梯度计算上。
\gls{nmomentum}中，梯度计算在施加当前速度之后。
因此，\gls{nmomentum}可以解释为往标准\gls{momentum}方法中添加了一个\emph{校正因子}。
完整的\,\gls{nmomentum}算法如\algref{alg:nesterov}所示。
% 292 mid


% 292 head
\begin{algorithm}[ht]
\caption{使用\,\gls{nmomentum}的\gls{SGD}（\glssymbol{SGD}）}
\label{alg:nesterov}
\begin{algorithmic}
\REQUIRE  \gls{learning_rate} $\epsilon$， \gls{momentum}参数 $\alpha$
\REQUIRE 初始参数 $\Vtheta$，初始速度 $\Vv$
\WHILE{没有达到停止\gls{criterion}}
    \STATE 从\gls{training_set}中采包含$m$个样本$\{ \Vx^{(1)},\dots, \Vx^{(m)}\}$ 的\gls{minibatch}，对应目标为$\Vy^{(i)}$。
    \STATE 应用临时更新： $\tilde{\Vtheta} \leftarrow \Vtheta  + \alpha \Vv$
         \STATE 计算梯度（在临时点）：$\Vg \leftarrow 
         \frac{1}{m} \nabla_{\tilde{\Vtheta}} \sum_i L(f(\Vx^{(i)};\tilde{\Vtheta}),\Vy^{(i)})$
    \STATE 计算速度更新：$\Vv \leftarrow \alpha \Vv - 
    \epsilon \Vg$
    \STATE 应用更新：$\Vtheta \leftarrow \Vtheta + \Vv$ 
\ENDWHILE
\end{algorithmic}
\end{algorithm}

% 292 head

% 292 mid

在凸\gls{batch}梯度的情况下，\gls{nmomentum}将\gls{excess_error}收敛率从$O(1/k)$（$k$步后）改进到$O(1/k^2)$，如~\cite{Nesterov83b}所示。
可惜，在随机梯度的情况下，\gls{nmomentum}没有改进收敛率。

% 292 mid

\section{参数初始化策略}
\label{sec:parameter_initialization_strategies}
有些优化算法本质上是非迭代的，只是求解一个解点。
有些其它优化算法本质上是迭代的，但是应用于这一类的优化问题时，能在可接受的时间内收敛到可接受的解，并且与初始值无关。
\gls{DL}训练算法通常没有这两种奢侈的性质。
\gls{DL}模型的训练算法通常是迭代的，因此要求使用者指定一些开始迭代的初始点。
此外，训练\gls{deep_model}是一个足够困难的问题，以致于大多数算法都很大程度地受到初始化选择的影响。
初始点能够决定算法是否收敛，有些初始点十分不稳定，使得该算法会遭遇数值困难，并完全失败。
当学习收敛时，初始点可以决定学习收敛得多快，以及是否收敛到一个\gls{cost}高或低的点。
此外，差不多\gls{cost}的点可以具有区别极大的\gls{generalization_error}，初始点也可以影响\gls{generalization}。

% 293 head

现代的初始化策略是简单的、启发式的。
设定改进的初始化策略是一项困难的任务，因为\gls{NN}优化至今还未被很好地理解。
大多数初始化策略基于在\gls{NN}初始化时实现一些很好的性质。
然而，我们并没有很好地理解这些性质中的哪些会在学习开始进行后的哪些情况下得以保持。
进一步的难点是，有些初始点从优化的观点看或许是有利的，但是从\gls{generalization}的观点看是不利的。
我们对于初始点如何影响\gls{generalization}的理解是相当原始的，几乎没有提供如何选择初始点的任何指导。

% 293 mid

也许完全确知的唯一特性是初始参数需要在不同单元间``破坏对称性''。
如果具有相同\gls{activation_function}的两个\gls{hidden_unit}连接到相同的输入，那么这些单元必须具有不同的初始参数。
如果它们具有相同的初始参数，然后应用到确定性损失和模型的确定性学习算法将一直以相同的方式更新这两个单元。
即使模型或训练算法能够使用随机性为不同的单元计算不同的更新（例如使用\,\gls{dropout}的训练），通常来说，最好还是初始化每个单元使其和其他单元计算不同的函数。
这或许有助于确保没有输入模式丢失在\gls{forward_propagation}的零空间中，没有梯度模式丢失在\gls{backward_propagation}的零空间中。
每个单元计算不同函数的目标促使了参数的随机初始化。
我们可以明确地搜索一大组彼此互不相同的基函数，但这经常会导致明显的计算代价。  
例如，如果我们有和输出一样多的输入，我们可以使用Gram-Schmidt正交化于初始的权重矩阵，保证每个单元计算彼此非常不同的函数。
在高维空间上使用高熵分布来随机初始化，计算代价小并且不太可能分配单元计算彼此相同的函数。

% 293 mid

通常情况下，我们可以为每个单元的\gls{bias_aff}设置启发式挑选的常数，仅随机初始化权重。
额外的参数（例如用于编码预测条件方差的参数）通常和偏置一样设置为启发式选择的常数。

% 293 end

我们几乎总是初始化模型的权重为高斯或均匀分布中随机抽取的值。
高斯或均匀分布的选择似乎不会有很大的差别，但也没有被详尽地研究。
然而，初始分布的大小确实对优化过程的结果和网络\gls{generalize}能力都有很大的影响。

% 294 head

更大的初始权重具有更强的破坏对称性的作用，有助于避免冗余的单元。
它们也有助于避免在每层线性成分的前向或\gls{backward_propagation}中丢失信号——矩阵中更大的值在矩阵乘法中有更大的输出。
如果初始权重太大，那么会在\gls{forward_propagation}或\gls{backward_propagation}中产生爆炸的值。
在循环网络中，很大的权重也可能导致\firstgls{chaos}（对于输入中很小的扰动非常敏感，导致确定性\gls{forward_propagation}过程表现随机）。
在一定程度上，梯度爆炸问题可以通过\gls{gradient_clipping}来缓解（执行\gls{GD}步骤之前设置梯度的阈值）。
较大的权重也会产生使得\gls{activation_function}饱和的值，导致饱和单元的梯度完全丢失。
这些竞争因素决定了权重的理想初始大小。
% 294 mid


关于如何初始化网络，\gls{regularization}和优化有着非常不同的观点。
优化观点建议权重应该足够大以成功传播信息，但是\gls{regularization}希望其小一点。
诸如\gls{SGD}这类对权重较小的增量更新，趋于停止在更靠近初始参数的区域（不管是由于卡在低梯度的区域，还是由于触发了基于\gls{overfitting} 的\gls{early_stopping}准则）的优化算法倾向于最终参数应接近于初始参数。
回顾\secref{sec:early_stopping}，在某些模型上，\gls{early_stopping}的\gls{GD}等价于\gls{weight_decay}。
在一般情况下，\gls{early_stopping}的\gls{GD}和\gls{weight_decay}不同，但是提供了一个宽松的类比去考虑初始化的影响。
我们可以将初始化参数$\Vtheta$为$\Vtheta_0$类比于强置均值为$\Vtheta_0$的高斯先验$p(\Vtheta)$。
从这个角度来看，选择$\Vtheta_0$接近$0$是有道理的。
这个先验表明，单元间彼此互不交互比交互更有可能。
只有在目标函数的似然项表达出对交互很强的偏好时，单元才会交互。
另一方面，如果我们初始化$\Vtheta_0$为很大的值，那么我们的先验指定了哪些单元应互相交互，以及它们应如何交互。
% 294 end


有些启发式方法可用于选择权重的初始大小。
一种初始化$m$个输入和$n$输出的全连接层的权重的启发式方法是从分布$U(-\frac{1}{\sqrt{m}}, \frac{1}{\sqrt{m}})$中采样权重，
而~\citet{GlorotAISTATS2010-small}建议使用\firstgls{normalized_initialization}
\begin{equation}
    W_{i,j} \sim U \left(-\sqrt{\frac{6}{m+n}}, \sqrt{\frac{6}{m+n}}\right) .
\end{equation}
后一种启发式方法初始化所有的层，折衷于使其具有相同激活方差和使其具有相同梯度方差之间。
这假设网络是不含非线性的链式矩阵乘法，据此推导得出。
现实的\gls{NN}显然会违反这个假设，但很多设计于线性模型的策略在其非线性对应中的效果也不错。
% 295 head


\cite{Saxe-et-al-ICLR13}推荐初始化为随机正交矩阵，仔细挑选负责每一层非线性缩放或\,\textbf{增益}(gain)因子$g$。
他们得到了用于不同类型的非线性\gls{activation_function}的特定缩放因子。
这种初始化方案也是启发于不含非线性的矩阵相乘序列的\gls{deep_network}。
在该模型下，这个初始化方案保证了达到收敛所需的训练迭代总数独立于深度。


增加缩放因子$g$将网络推向网络\gls{forward_propagation}时激活范数增加，\gls{backward_propagation}时梯度范数增加的区域。
\cite{Sussillo14}表明，正确设置缩放因子足以训练深达$1000$层的网络，而不需要使用正交初始化。
这种方法的一个重要观点是，在\gls{feedforward_network}中，激活和梯度会在每一步\gls{forward_propagation}或\gls{backward_propagation}中增加或缩小，遵循随机游走行为。
这是因为\gls{feedforward_network}在每一层使用了不同的权重矩阵。
如果该随机游走调整到保持范数，那么\gls{feedforward_network}能够很大程度地避免相同权重矩阵用于每层的\gls{vanish_explode_gradient}，如\secref{sec:long_term_dependencies}所述。
% 295 end


可惜，这些初始权重的最佳准则往往不会带来最佳效果。
这可能有三种不同的原因。
首先，我们可能使用了错误的标准——它实际上并不利于保持整个网络信号的范数。
其次，初始化时强加的性质可能在学习开始进行后不能保持。
最后，该标准可能成功提高了优化速度，但意外地增大了\gls{generalization_error}。
在实践中，我们通常需要将权重范围视为\gls{hyperparameter}，其最优值大致接近，但并不完全等于理论预测。
% 296 head


数值范围准则的一个缺点是，设置所有的初始权重具有相同的标准差，例如$\frac{1}{\sqrt{m}}$，会使得层很大时每个单一权重会变得极其小。
\cite{martens2010hessian-small}提出了一种被称为\firstgls{sparse_initialization}的替代方案，每个单元初始化为恰好有$k$个非零权重。
这个想法保持该单元输入的总数量独立于输入数目$m$，而不使单一权重元素的大小随$m$缩小。
稀疏初始化有助于实现单元之间在初始化时更具多样性。
但是，获得较大取值的权重也同时被加了很强的先验。
因为\gls{GD}需要很长时间缩小``不正确''的大值，这个初始化方案可能会导致某些单元出问题，例如\,\gls{maxout}\,单元有几个过滤器，互相之间必须仔细调整。
% 296 mid


计算资源允许的话，将每层权重的初始数值范围设为\gls{hyperparameter}通常是个好主意，使用\secref{sec:automatic_hyperparameter_optimization_algorithms}介绍的\gls{hyperparameter}搜索算法，如随机搜索，挑选这些数值范围。
是否选择使用密集或稀疏初始化也可以设为一个\gls{hyperparameter}。
作为替代，我们可以手动搜索最优初始范围。
一个好的挑选初始数值范围的经验法则是观测单个\gls{minibatch}数据上的激活或梯度的幅度或标准差。
如果权重太小，那么当激活值在\gls{minibatch}上\gls{forward_propagation}于网络时，激活值的幅度会缩小。
通过重复识别具有小得不可接受的激活值的第一层，并提高其权重，最终有可能得到一个初始激活全部合理的网络。
如果学习在这点上仍然很慢，观测梯度的幅度或标准差可能也会有所帮助。
这个过程原则上是自动的，且通常计算量低于基于\gls{validation_set}误差的\gls{hyperparameter}优化，因为它是基于初始模型在单批数据上的行为反馈，而不是在\gls{validation_set}上训练模型的反馈。
由于这个协议很长时间都被启发式使用，最近~\cite{mishkin2015all}更正式地研究了该协议。
% 296 mid


目前为止，我们关注在权重的初始化上。
幸运的是，其他参数的初始化通常更容易。
% 296 end


设置\gls{bias_aff}的方法必须和设置权重的方法协调。
设置\gls{bias_aff}为零通常在大多数权重初始化方案中是可行的。
存在一些我们可能设置\gls{bias_aff}为非零值的情况：
% 297 head

\begin{itemize}
\item 如果\gls{bias_aff}是作为输出单元，那么初始化\gls{bias_aff}以获取正确的输出边缘统计通常是有利的。
要做到这一点，我们假设初始权重足够小，该单元的输出仅由\gls{bias_aff}决定。
这说明设置\gls{bias_aff}为应用于\gls{training_set}上输出边缘统计的\gls{activation_function}的逆。
例如，如果输出是类上的分布，且该分布是高度偏态分布，第$i$类的边缘概率由某个向量$\Vc$的第$i$个元素给定，那么我们可以通过求解方程$\text{softmax}(\Vb)=\Vc$来设置偏置向量$\Vb$。
这不仅适用于分类器，也适用于我们将在第三部分遇到的模型，例如\gls{AE}和\gls{BM}。
这些模型拥有输出类似于输入数据$\Vx$的网络层，初始化这些层的偏置以匹配$\Vx$上的边缘分布将有助于模型学习。
% 297 mid


\item 有时，我们可能想要选择\gls{bias_aff}以避免初始化引起太大饱和。
例如，我们可能会将ReLU的\gls{hidden_unit}设为$0.1$而非$0$，以避免ReLU在初始化时饱和。
尽管这种方法违背不希望偏置具有很强输入的权重初始化准则。
例如，不建议使用随机游走初始化\citep{Sussillo14}。
% 297 mid


\item 有时，一个单元会控制其他单元能否参与到等式中。
在这种情况下，我们有一个单元输出$u$，另一个单元$h\in[0,1]$，那么我们可以将$h$视作门，以决定$uh\approx 1$还是$uh\approx 0$。
在这种情形下，我们希望设置\gls{bias_aff} $h$，使得在初始化的大多数情况下$h\approx 1$。
否则，$u$没有机会学习。
例如，\cite{Jozefowicz-et-al-ICML2015}提议设置~\glssymbol{LSTM}~模型遗忘门的\gls{bias_aff}为$1$，如\secref{sec:the_long_short_term_memory_and_other_gated_rnns}所述。
\end{itemize}
% 297 end


另一种常见类型的参数是方差或精确度参数。
例如，我们用以下模型进行带条件方差估计的\gls{linear_regression}
\begin{equation}
    p(y\mid\Vx) = \mathcal{N} (y \mid \Vw^\top \Vx + b, 1/\beta) ,
\end{equation}
其中$\beta$是精确度参数。
通常我们能安全地初始化方差或精确度参数为$1$。
另一种方法假设初始权重足够接近零，设置偏置可以忽略权重的影响，然后设定偏置以产生输出的正确边缘均值，并将方差参数设置为\gls{training_set}输出的边缘方差。
% 298 head


除了这些初始化模型参数的简单常数或随机方法，还有可能使用\gls{ML}初始化模型参数。
在本书第三部分讨论的一个常用策略是使用相同的输入数据集，用无监督模型训练出来的参数来初始化监督模型。
我们也可以在相关问题上使用监督训练。
即使是在一个不相关的任务上运行监督训练，有时也能得到一个比随机初始化具有更快收敛率的初始值。
这些初始化策略有些能够得到更快的收敛率和更好的\gls{generalization_error}，因为它们编码了模型初始参数的分布信息。
其他策略显然效果不错的原因主要在于它们设置参数为正确的数值范围，或是设置不同单元计算互相不同的函数。
% 298 mid


\section{自适应\glsentrytext{learning_rate}算法}
\label{sec:algorithms_with_adaptive_learning_rates}
\gls{NN}研究员早就意识到\gls{learning_rate}肯定是难以设置的\gls{hyperparameter}之一，因为它对模型的性能有显著的影响。
正如我们在\secref{sec:gradient_based_optimization}和\secref{sec:challenges_in_neural_network_optimization}中所探讨的，损失通常高度敏感于参数空间中的某些方向，而不敏感于其他。
\gls{momentum}算法可以在一定程度缓解这些问题，但这样做的代价是引入了另一个\gls{hyperparameter}。
在这种情况下，自然会问有没有其他方法。
如果我们相信方向敏感度在某种程度是轴对齐的，那么每个参数设置不同的\gls{learning_rate}，在整个学习过程中自动适应这些\gls{learning_rate}是有道理的。



\textbf{Delta-bar-delta}算法\citep{jacobs1988}是一个早期的在训练时适应模型参数各自\gls{learning_rate}的启发式方法。
该方法基于一个很简单的想法，如果损失对于某个给定模型参数的偏导保持相同的符号，那么\gls{learning_rate}应该增加。如果对于该参数的偏导变化了符号，那么\gls{learning_rate}应减小。
当然，这种方法只能应用于全\gls{batch}优化中。
% 298 mid


最近，提出了一些增量（或者基于\gls{minibatch}）的算法来自适应模型参数的\gls{learning_rate}。
这节将简要回顾其中一些算法。
% 298 end


% 299 head
\subsection{\glsentrytext{adagrad}}
\label{sec:adagrad}
\textbf{AdaGrad}算法，如\algref{alg:ada_grad}所示，独立地适应所有模型参数的\gls{learning_rate}，缩放每个参数反比于其所有梯度历史平方值总和的平方根\citep{Duchi+al-2011}。
具有损失最大偏导的参数相应地有一个快速下降的\gls{learning_rate}，而具有小偏导的参数在\gls{learning_rate}上有相对较小的下降。
净效果是在参数空间中更为平缓的倾斜方向会取得更大的进步。
% 299 head


在\gls{convex_optimization}背景中，\gls{adagrad} 算法具有一些令人满意的理论性质。
然而，经验上已经发现，对于训练\gls{DNN}模型而言，\emph{从训练开始时}积累梯度平方会导致有效\gls{learning_rate}过早和过量的减小。
\gls{adagrad}\,在某些\gls{DL}模型上效果不错，但不是全部。


\begin{algorithm}[ht]
\caption{AdaGrad算法}
\label{alg:ada_grad}
\begin{algorithmic}
\REQUIRE 全局\gls{learning_rate} $\epsilon$
\REQUIRE 初始参数$\Vtheta$
\REQUIRE 小常数$\delta$，为了数值稳定大约设为$10^{-7}$
\STATE 初始化梯度累积变量$\Vr = 0$
\WHILE{没有达到停止\gls{criterion}}
    \STATE 从\gls{training_set}中采包含$m$个样本$\{ \Vx^{(1)},\dots, \Vx^{(m)}\}$ 的\gls{minibatch}，对应目标为$\Vy^{(i)}$。
    \STATE 计算梯度： $\Vg \leftarrow  
         \frac{1}{m} \nabla_{\Vtheta} \sum_i L(f(\Vx^{(i)};\Vtheta),\Vy^{(i)})$ 
    \STATE 累积平方梯度：$\Vr \leftarrow \Vr + \Vg \odot \Vg$
    \STATE 计算更新：$\Delta \Vtheta \leftarrow -
    \frac{\epsilon}{\delta+ \sqrt{\Vr}} \odot\Vg$  \ \  （逐元素地应用除和求平方根）
    \STATE 应用更新：$\Vtheta \leftarrow \Vtheta + \Delta \Vtheta$
\ENDWHILE
\end{algorithmic}
\end{algorithm}


\subsection{RMSProp}
\label{sec:rmsprop}
\textbf{RMSProp}算法\citep{Hinton-ipam2012}修改AdaGrad以在\gls{nonconvex}设定下效果更好，改变梯度积累为指数加权的移动平均。
\gls{adagrad}\,旨在应用于凸问题时快速收敛。
当应用于\gls{nonconvex}函数训练\gls{NN}时，学习轨迹可能穿过了很多不同的结构，最终到达一个局部是凸碗的区域。
AdaGrad根据平方梯度的整个历史收缩\gls{learning_rate}，可能使得\gls{learning_rate}在达到这样的凸结构前就变得太小了。
RMSProp使用指数衰减平均以丢弃遥远过去的历史，使其能够在找到凸碗状结构后快速收敛，
它就像一个初始化于该碗状结构的AdaGrad算法实例。

% -- 299 --

RMSProp的标准形式如\algref{alg:rms_prop}所示，结合Nesterov动量的形式如\algref{alg:rms_nesterov}所示。
相比于AdaGrad，使用移动平均引入了一个新的\gls{hyperparameter}$\rho$，用来控制移动平均的长度范围。

% -- 300 --

经验上，RMSProp已被证明是一种有效且实用的\gls{DNN}优化算法。
目前它是\gls{DL}从业者经常采用的优化方法之一。


\begin{algorithm}[ht]
\caption{RMSProp算法}
\label{alg:rms_prop}
\begin{algorithmic}
\REQUIRE 全局\gls{learning_rate} $\epsilon$，衰减速率$\rho$
\REQUIRE  初始参数$\Vtheta$
\REQUIRE 小常数$\delta$，通常设为$10^{-6}$（用于被小数除时的数值稳定）
\STATE 初始化累积变量 $\Vr = 0$
\WHILE{没有达到停止\gls{criterion}}
    \STATE 从\gls{training_set}中采包含$m$个样本$\{ \Vx^{(1)},\dots, \Vx^{(m)}\}$ 的\gls{minibatch}，对应目标为$\Vy^{(i)}$。
    \STATE 计算梯度：$\Vg \leftarrow  
         \frac{1}{m} \nabla_{\Vtheta} \sum_i L(f(\Vx^{(i)};\Vtheta),\Vy^{(i)})$ 
    \STATE 累积平方梯度：$\Vr \leftarrow \rho
    \Vr + (1-\rho) \Vg \odot \Vg$
    \STATE 计算参数更新：$\Delta \Vtheta =
    -\frac{\epsilon}{\sqrt{\delta + \Vr}} \odot \Vg$  \ \  ($\frac{1}{\sqrt{\delta + \Vr}}$ 逐元素应用)
    \STATE 应用更新：$\Vtheta \leftarrow \Vtheta + \Delta \Vtheta$
\ENDWHILE
\end{algorithmic}
\end{algorithm}

\begin{algorithm}[ht]
\caption{使用Nesterov\,\gls{momentum}的RMSProp算法}
\label{alg:rms_nesterov}
\begin{algorithmic}
\REQUIRE 全局\gls{learning_rate} $\epsilon$，衰减速率$\rho$， \gls{momentum}系数$\alpha$
\REQUIRE 初始参数$\Vtheta$，初始参数$\Vv$
\STATE 初始化累积变量 $\Vr = 0$
\WHILE{没有达到停止\gls{criterion}} % NOTE: do not capitalize the condition
    \STATE 从\gls{training_set}中采包含$m$个样本$\{ \Vx^{(1)},\dots, \Vx^{(m)}\}$ 的\gls{minibatch}，对应目标为$\Vy^{(i)}$。
    \STATE 计算临时更新：$\tilde{\Vtheta} \leftarrow \Vtheta + \alpha \Vv$
    \STATE 计算梯度：$\Vg \leftarrow  
         \frac{1}{m} \nabla_{\tilde{\Vtheta}} \sum_i L(f(\Vx^{(i)};\tilde{\Vtheta}),\Vy^{(i)})$ 
    \STATE  累积梯度：$\Vr \leftarrow \rho
    \Vr + (1-\rho) \Vg \odot \Vg$
    \STATE  计算速度更新：$\Vv \leftarrow \alpha \Vv
    -\frac{\epsilon}{\sqrt{\Vr}} \odot \Vg$ \ \  ($\frac{1}{\sqrt{\Vr}}$ 逐元素应用)
    \STATE 应用更新：$\Vtheta \leftarrow \Vtheta + \Vv$
\ENDWHILE
\end{algorithmic}
\end{algorithm}


\subsection{Adam}
\label{sec:adam}
\textbf{Adam}~\citep{kingma2014adam}是另一种\gls{learning_rate}自适应的优化算法，如\algref{alg:adam}所示。
``Adam''这个名字派生自短语``adaptive moments''。
早期算法背景下，它也许最好被看作结合RMSProp和具有一些重要区别的\gls{momentum}的变种。
首先，在Adam中，\gls{momentum}直接并入了梯度一阶矩（指数加权）的估计。
将\gls{momentum}加入RMSProp最直观的方法是将\gls{momentum}应用于缩放后的梯度。
结合缩放的\gls{momentum}使用没有明确的理论动机。
其次，Adam包括偏置修正，修正从原点初始化的一阶矩（\gls{momentum}项）和（非中心的）二阶矩的估计（\algref{alg:adam}）。
RMSProp也采用了（非中心的）二阶矩估计，然而缺失了修正因子。
因此，不像Adam，RMSProp二阶矩估计可能在训练初期有很高的偏置。
Adam通常被认为对\gls{hyperparameter}的选择相当鲁棒，尽管\gls{learning_rate}有时需要从建议的默认修改。

\begin{algorithm}[ht]
\caption{Adam算法}
\label{alg:adam}
\begin{algorithmic}
\REQUIRE 步长 $\epsilon$ （建议默认为： $0.001$）
\REQUIRE 矩估计的指数衰减速率， $\rho_1$ 和 $\rho_2$ 在区间 $[0, 1)$内。
（建议默认为：分别为$0.9$ 和 $0.999$）
\REQUIRE 用于数值稳定的小常数 $\delta$  （建议默认为： $10^{-8}$）
\REQUIRE 初始参数 $\Vtheta$
\STATE 初始化一阶和二阶矩变量 $\Vs = 0 $, $\Vr = 0$
\STATE 初始化\gls{time_step} $t=0$ 
\WHILE{没有达到停止\gls{criterion}}
    \STATE 从\gls{training_set}中采包含$m$个样本$\{ \Vx^{(1)},\dots, \Vx^{(m)}\}$ 的\gls{minibatch}，对应目标为$\Vy^{(i)}$。
    \STATE 计算梯度：$\Vg \leftarrow \frac{1}{m} \nabla_{\Vtheta} \sum_i L(f(\Vx^{(i)};\Vtheta),\Vy^{(i)})$ 
    \STATE $t \leftarrow t + 1$
    \STATE 更新有偏一阶矩估计： $\Vs \leftarrow \rho_1 \Vs + (1-\rho_1) \Vg$
    \STATE 更新有偏二阶矩估计：$\Vr \leftarrow \rho_2 \Vr + (1-\rho_2) \Vg \odot \Vg$
    \STATE 修正一阶矩的\gls{bias_sta}：$\hat{\Vs} \leftarrow \frac{\Vs}{1-\rho_1^t}$
    \STATE 修正二阶矩的\gls{bias_sta}：$\hat{\Vr} \leftarrow \frac{\Vr}{1-\rho_2^t}$
    \STATE 计算更新：$\Delta \Vtheta = - \epsilon \frac{\hat{\Vs}}{\sqrt{\hat{\Vr}} + \delta}$ \ \  （逐元素应用操作）
    \STATE 应用更新：$\Vtheta \leftarrow \Vtheta + \Delta \Vtheta$
\ENDWHILE
\end{algorithmic}
\end{algorithm}


% -- 301 --

\subsection{选择正确的优化算法}
\label{sec:choosing_the_right_optimization_algorithms}
在本节中，我们讨论了一系列算法，通过自适应每个模型参数的\gls{learning_rate}以解决优化\gls{deep_model}中的难题。
此时，一个自然的问题是：该选择哪种算法呢？

遗憾的是，目前在这一点上没有达成共识。
\cite{Schaul2014_unittests}展示了许多优化算法在大量学习任务上极具价值的比较。
虽然结果表明，具有自适应\gls{learning_rate}（以RMSProp和AdaDelta为代表）的算法族表现得相当鲁棒，不分伯仲，但没有哪个算法能脱颖而出。

目前，最流行并且使用很高的优化算法包括SGD、具\gls{momentum}的SGD、RMSProp、具\gls{momentum}的RMSProp、AdaDelta和Adam。
此时，选择哪一个算法似乎主要取决于使用者对算法的熟悉程度（以便调节\gls{hyperparameter}）。

\section{二阶近似方法}
\label{sec:approximate_second_order_methods}
在本节中，我们会讨论训练\gls{DNN}的二阶方法。
参考\cite{LeCun+98backprop}了解该问题的早期处理方法。
为表述简单起见，我们只考察\gls{objective_function}为经验风险：
\begin{equation}
    J(\Vtheta) = \SetE_{\RVx, \RSy \sim \hat{p}_{\text{data}}(\Vx,y) } [ L(f(\Vx; \Vtheta), y) ] =
\frac{1}{m} \sum_{i=1}^m L(f(\Vx^{(i)}; \Vtheta), y^{(i)}).
\end{equation}
然而，我们在这里讨论的方法很容易扩展到更一般的\gls{objective_function}，例如，\chapref{chap:regularization_for_deep_learning}讨论的包括参数正则项的函数。

% -- 302 --

\subsection{\glsentrytext{newton_method}}
\label{sec:newton_method}
在\secref{sec:gradient_based_optimization}，我们介绍了二阶梯度方法。
与一阶方法相比，二阶方法使用二阶导数改进了优化。
最广泛使用的二阶方法是\gls{newton_method}。
我们现在更详细地描述\gls{newton_method}，重点在其应用于\gls{NN}的训练。

\gls{newton_method}是基于二阶泰勒级数展开在某点$\Vtheta_0$附近来近似$J(\Vtheta)$的优化方法，其忽略了高阶导数：
\begin{equation}
    J(\Vtheta) \approx J(\Vtheta_0) + (\Vtheta - \Vtheta_0)^\top \nabla_{\Vtheta}   
    J(\Vtheta_0) + \frac{1}{2} (\Vtheta - \Vtheta_0)^\top \MH(\Vtheta - \Vtheta_0),
\end{equation}
其中$\MH$是$J$相对于$\Vtheta$的\,\gls{hessian}\,矩阵在$\Vtheta_0$处的估计。
如果我们再求解这个函数的\gls{critical_points}，我们将得到牛顿参数更新规则：
\begin{equation}
    \Vtheta^* = \Vtheta_0 - \MH^{-1}\nabla_{\Vtheta} J(\Vtheta_0).
\label{eq:8.27}
\end{equation}
因此，对于局部的二次函数（具有正定的$\MH$\,），用$\MH^{-1}$重新调整梯度，\gls{newton_method}会直接跳到极小值。
如果\gls{objective_function}是凸的但非二次的（有高阶项），该更新将是迭代的，得到和\gls{newton_method}相关的算法，如\algref{alg:newton}所示。

对于非二次的表面，只要\,\gls{hessian}\,矩阵保持正定，\gls{newton_method}能够迭代地应用。
这意味着一个两步迭代过程。
首先，更新或计算\,\gls{hessian}\,逆（通过更新二阶近似）。
其次，根据\eqnref{eq:8.27}更新参数。

% -- 303 --

在\secref{sec:plateaus_saddle_points_and_other_flat_regions}，我们讨论了\gls{newton_method}只适用于\,\gls{hessian}\,矩阵是正定的情况。
在\gls{DL}中，\gls{objective_function}的表面通常\gls{nonconvex}（有很多特征），如\gls{saddle_points}。
因此使用\gls{newton_method}是有问题的。
如果\,\gls{hessian}\,矩阵的特征值并不都是正的，例如，靠近\gls{saddle_points}处，\gls{newton_method}实际上会导致更新朝错误的方向移动。
这种情况可以通过正则化\,\gls{hessian}\,矩阵来避免。
常用的正则化策略包括在\,\gls{hessian}\,矩阵对角线上增加常数$\alpha$。
正则化更新变为
\begin{equation}
    \Vtheta^* = \Vtheta_0 - [ H( f(\Vtheta_0)) + \alpha \MI  ]^{-1} \nabla_{\Vtheta} f(\Vtheta_0).
\end{equation}
这个正则化策略用于\gls{newton_method}的近似，例如Levenberg-Marquardt算法\citep{Levenberg44,Marquardt63}，只要\,\gls{hessian}\,矩阵的负特征值仍然相对接近零，效果就会很好。
在\gls{curvature}方向更极端的情况下，$\alpha$的值必须足够大，以抵消负特征值。
然而，如果$\alpha$持续增加，\gls{hessian}\,矩阵会变得由对角矩阵$\alpha \MI$主导，通过\gls{newton_method}所选择的方向会收敛到普通梯度除以$\alpha$。
当很强的负\gls{curvature}存在时，$\alpha$可能需要特别大，以致于\gls{newton_method}比选择合适\gls{learning_rate}的\gls{GD}的步长更小。

\begin{algorithm}[ht]
\caption{目标为$J(\Vtheta)= \frac{1}{m} \sum_{i=1}^m L(f(\Vx^{(i)};\Vtheta), y^{(i)})$的\gls{newton_method}}
\label{alg:newton}
\begin{algorithmic}
\REQUIRE 初始参数$\Vtheta_{0}$
\REQUIRE 包含 $m$个样本的\gls{training_set}
\WHILE{没有达到停止\gls{criterion}} 
      \STATE 计算梯度： $\Vg \leftarrow 
     \frac{1}{m} \nabla_{\Vtheta} \sum_i L(f(\Vx^{(i)};\Vtheta),\Vy^{(i)})$ 
      \STATE 计算\,\gls{hessian}\,矩阵：$\MH \leftarrow  
     \frac{1}{m} \nabla_{\Vtheta}^2 \sum_i L(f(\Vx^{(i)};\Vtheta),\Vy^{(i)})$ 
    \STATE 计算\,\gls{hessian}\,逆：$\MH^{-1}$
    \STATE 计算更新： $\Delta \Vtheta = - \MH^{-1} \Vg$
    \STATE 应用更新：$\Vtheta = \Vtheta+\Delta \Vtheta$
\ENDWHILE
\end{algorithmic}
\end{algorithm}


除了\gls{objective_function}的某些特征带来的挑战，如\gls{saddle_points}，\gls{newton_method}用于训练大型\gls{NN}还受限于其显著的计算负担。
\gls{hessian}\,矩阵中元素数目是参数数量的平方，因此，如果参数数目为$k$（甚至是在非常小的\gls{NN}中$k$也可能是百万级别），\gls{newton_method}需要计算$k\times k$矩阵的逆，计算复杂度为$O(k^3)$。
另外，由于参数将每次更新都会改变，\emph{每次训练迭代}都需要计算\,\gls{hessian}\,矩阵的逆。
其结果是，只有参数很少的网络才能在实际中用\gls{newton_method}训练。
在本节的剩余部分，我们将讨论一些试图保持\gls{newton_method}优点，同时避免计算障碍的替代算法。

\subsection{\glsentrytext{CG}法}
\label{sec:conjugate_gradients}
\gls{CG}法是一种通过迭代下降的\firstgls{conjugate_directions}以有效避免\,\gls{hessian}\,矩阵求逆计算的方法。
这种方法的灵感来自于对最速下降方法弱点的仔细研究（详细信息请查看\secref{sec:gradient_based_optimization}），其中线搜索迭代地用于与梯度相关的方向上。
\figref{fig:chap8_steepest_descent_quadratic}说明了该方法在二次碗型目标中如何表现的，是一个相当低效的来回往复，锯齿形模式。
这是因为每一个由梯度给定的线搜索方向，都保证正交于上一个线搜索方向。

\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter8/figures/steepest_descent_quadratic_color}}
\fi
\caption{将最速下降法应用于二次代价表面。
在每个步骤，最速下降法沿着由初始点处的梯度定义的线跳到最低代价的点。
这解决了\figref{fig:chap4_poor_conditioning_color}中使用固定\gls{learning_rate}所遇到的一些问题，但即使使用最佳步长，算法仍然朝最优方向曲折前进。
根据定义，在沿着给定方向的目标最小值处，最终点处的梯度与该方向正交。
}
\label{fig:chap8_steepest_descent_quadratic}
\end{figure}


% -- 304 --

假设上一个搜索方向是$\Vd_{t-1}$。   
在极小值处，线搜索终止，方向$\Vd_{t-1}$处的方向导数为零：$\nabla_{\Vtheta} J(\Vtheta) \cdot \Vd_{t-1} = 0$。
因为该点的梯度定义了当前的搜索方向，$\Vd_t = \nabla_{\Vtheta} J(\Vtheta)$将不会贡献于方向$\Vd_{t-1}$。
因此方向$\Vd_t$正交于$\Vd_{t-1}$。
最速下降多次迭代中，方向$\Vd_{t-1}$和$\Vd_t$之间的关系如\figref{fig:chap8_steepest_descent_quadratic}所示。
如图展示的，下降正交方向的选择不会保持前一搜索方向上的最小值。
这产生了锯齿形的过程。
在当前梯度方向下降到极小值，我们必须重新最小化之前梯度方向上的目标。
因此，通过遵循每次线搜索结束时的梯度，我们在某种程度上撤销了在之前线搜索的方向上取得的进展。
\gls{CG}法试图解决这个问题。

在\gls{CG}法中，我们寻求一个和先前线搜索方向\firstgls{conjugate}的搜索方向，即它不会撤销该方向上的进展。
在训练迭代$t$时，下一步的搜索方向$\Vd_t$的形式如下：
\begin{equation}
    \Vd_t = \nabla_{\Vtheta} J(\Vtheta) + \beta_t \Vd_{t-1},
\end{equation}
其中，系数$\beta_t$的大小控制我们应沿方向$\Vd_{t-1}$加回多少到当前搜索方向上。

% -- 305 --

如果$\Vd_t^\top \MH \Vd_{t-1} = 0$，其中$\MH$是\,\gls{hessian}\,矩阵，则两个方向$\Vd_t$和$\Vd_{t-1}$被称为共轭的。

适应共轭的直接方法会涉及到$\MH$特征向量的计算以选择$\beta_t$。
这将无法满足我们的开发目标：寻找在大问题比\gls{newton_method}计算更加可行的方法。
我们能否不进行这些计算而得到共轭方向？
幸运的是这个问题的答案是肯定的。

两种用于计算$\beta_t$的流行方法是：
\begin{enumerate}
\item Fletcher-Reeves:
\begin{equation}
    \beta_t = \frac{ \nabla_{\Vtheta} J(\Vtheta_t)^\top \nabla_{\Vtheta} J(\Vtheta_t) }
{ \nabla_{\Vtheta} J(\Vtheta_{t-1})^\top \nabla_{\Vtheta} J(\Vtheta_{t-1}) }
\end{equation}

\item Polak-Ribi\`{e}re:
\begin{equation}
    \beta_t = \frac{ (\nabla_{\Vtheta} J(\Vtheta_t) - \nabla_{\Vtheta} J(\Vtheta_{t-1}))^\top \nabla_{\Vtheta} J(\Vtheta_t) }
{ \nabla_{\Vtheta} J(\Vtheta_{t-1})^\top \nabla_{\Vtheta} J(\Vtheta_{t-1}) }
\end{equation}
\end{enumerate}
对于二次曲面而言，共轭方向确保梯度沿着前一方向大小不变。
因此，我们在前一方向上仍然是极小值。
其结果是，在$k$-维参数空间中，\gls{CG}法只需要至多$k$次线搜索就能达到极小值。
\gls{CG}法如\algref{alg:cg}所示。

\begin{algorithm}[ht]
\caption{\gls{CG}法}
\label{alg:cg}
\begin{algorithmic}
\REQUIRE 初始参数 $\Vtheta_{0}$
\REQUIRE 包含$m$个样本的\gls{training_set}
\STATE 初始化 $\Vrho_{0} = 0$
\STATE 初始化 $g_0 = 0$
\STATE 初始化 $t = 1$
\WHILE{没有达到停止\gls{criterion}}
    \STATE 初始化梯度 ${\Vg}_{t} = 0$
    \STATE 计算梯度：$\Vg_{t} \leftarrow
         \frac{1}{m}\nabla_{\Vtheta} \sum_i L(f(\Vx^{(i)};\Vtheta),\Vy^{(i)})$ 
    \STATE 计算 $\beta_{t} = \frac{(\Vg_{t}-\Vg_{t-1})^\top \Vg_{t}}{\Vg_{t-1}^\top \Vg_{t-1}}$  (Polak-Ribi\`{e}re)
    \STATE (非线性\gls{CG}法：视情况可重置$\beta_{t}$为零，
           例如  $t$是常数$k$的倍数时，如 $k=5$)
    \STATE 计算搜索方向： $\Vrho_{t} = -\Vg_{t} + \beta_{t} \Vrho_{t-1}$ 
    \STATE 执行\gls{line_search}寻找：$\epsilon^{*} = \arg\!\min_{\epsilon}
    \frac{1}{m} \sum_{i=1}^{m}L(f(\Vx^{(i)};\Vtheta_t + \epsilon \Vrho_t),\Vy^{(i)})$ 
    \STATE （对于真正二次的\gls{cost_function}，存在$\epsilon^*$的解析解，而无需显式地搜索）
    \STATE 应用更新：$\Vtheta_{t+1} = \Vtheta_{t}+ \epsilon^{*} \Vrho_{t}$
    \STATE $t \leftarrow t + 1$
\ENDWHILE
\end{algorithmic}
\end{algorithm}


\paragraph{\gls{nonlinear_CG}法：}
目前，我们已经讨论了用于二次\gls{objective_function}的\gls{CG}法。
当然，本章我们主要关注于探索训练\gls{NN}和其他相关\gls{DL}模型的优化方法，其对应的\gls{objective_function}比二次函数复杂得多。
或许令人惊讶，\gls{CG}法在这种情况下仍然是适用的，尽管需要作一些修改。
没有目标是二次的保证，共轭方向也不再保证在以前方向上的目标仍是极小值。
其结果是，\textbf{\gls{nonlinear_CG}法}\,算法会包括一些偶尔的重设，\gls{CG}法沿未修改的梯度重启线搜索。

% -- 306 --

实践者报告在实践中使用\gls{nonlinear_CG}法训练\gls{NN}是合理的，尽管在开始\gls{nonlinear_CG}法前使用\gls{SGD}迭代若干步来初始化效果更好。
另外，尽管（非线性）\gls{CG}法传统上作为批方法，\gls{minibatch}版本已经成功用于训练\gls{NN}~\citep{Le-ICML2011}。
针对神经网路的\gls{CG}法应用早已被提出，例如缩放的\gls{CG}法\citep{Moller}。

\subsection{\glsentrytext{BFGS}}
\label{sec:bfgs}
\textbf{Broyden-Fletcher-Goldfarb-Shanno}（\textbf{\gls{BFGS}}）算法具有\gls{newton_method}的一些优点，但没有\gls{newton_method}的计算负担。
在这方面，\gls{BFGS}\,和\gls{CG}法很像。
然而，\gls{BFGS}\,使用了一个更直接的方法近似牛顿更新。回顾牛顿更新由下式给出
\begin{equation}
    \Vtheta^* = \Vtheta_0 - \MH^{-1} \nabla_{\Vtheta} J(\Vtheta_0),
\end{equation}
其中，$\MH$是$J$相对于$\Vtheta$的\,\gls{hessian}\,矩阵在$\Vtheta_0$处的估计。
运用\gls{newton_method}的主要计算难点在于计算\,\gls{hessian}\,逆$\MH^{-1}$。
拟\gls{newton_method}所采用的方法（\gls{BFGS}\,是其中最突出的）是使用矩阵$\MM_t$近似逆，迭代地低秩更新精度以更好地近似$\MH^{-1}$。

% -- 307 --

\gls{BFGS}\,近似的说明和推导出现在很多关于优化的教科书中，包括\cite{Lue84}。

当\,\gls{hessian}\,逆近似$\MM_t$更新时，下降方向$\Vrho_t$为$\Vrho_t = \MM_t \Vg_t$。
该方向上的线搜索用于决定该方向上的步长$\epsilon^*$。
参数的最后更新为：
\begin{equation}
    \Vtheta_{t+1} = \Vtheta_t + \epsilon^* \Vrho_t.
\end{equation}

和\gls{CG}法相似，\gls{BFGS}\,算法迭代一系列线搜索，其方向含二阶信息。
然而和\gls{CG}法不同的是，该方法的成功并不严重依赖于线搜索寻找该方向上和真正极小值很近的一点。
因此，相比于\gls{CG}法，\gls{BFGS}\,的优点是其花费较少的时间改进每个线搜索。
在另一方面，\gls{BFGS}\,算法必须存储\,\gls{hessian}\,逆矩阵$\MM$，需要$O(n^2)$的存储空间，使\,\gls{BFGS}\,不适用于大多数具有百万级参数的现代\gls{DL}模型。

\paragraph{存储受限的\,\gls{BFGS}（或\,\gls{LBFGS}）}
通过避免存储完整的\,\gls{hessian}\,逆近似$\MM$，\gls{BFGS}\,算法的存储代价可以显著降低。
\gls{LBFGS}\,算法使用和\,\gls{BFGS}\,算法相同的方法计算$\MM$的近似，但起始假设是$\MM^{(t-1)}$是单位矩阵，而不是一步一步都要存储近似。
如果使用精确的线搜索，\gls{LBFGS}\,定义的方向会是相互共轭的。
然而，不同于\gls{CG}法，即使只是近似线搜索的极小值，该过程的效果仍然不错。
这里描述的无存储的\,\gls{LBFGS}\,方法可以拓展为包含\,\gls{hessian}\,矩阵更多的信息，每步存储一些用于更新$\MM$的向量，且每步的存储代价是$O(n)$。

% -- 308 --

\section{优化策略和元算法}
\label{sec:optimization_strategies_and_meta_algorithms}
许多优化技术并非真正的算法，而是一般化的模板，可以特定地产生算法，或是并入到很多不同的算法中。

\subsection{\glsentrytext{Batch_normalization}}
\label{sec:batch_normalization}
\gls{batch_normalization}~\citep{Ioffe+Szegedy-2015}是优化\gls{DNN}中最激动人心的最新创新之一。
实际上它并不是一个优化算法，而是一个自适应的重参数化的方法，试图解决训练非常深的模型的困难。

非常深的模型会涉及多个函数或层组合。
在其他层不改变的假设下，梯度用于如何更新每一个参数。
在实践中，我们同时更新所有层。
当我们进行更新时，可能会发生一些意想不到的结果，这是因为许多组合在一起的函数同时改变时，计算更新的假设是其他函数保持不变。
举一个简单的例子，假设我们有一个\gls{DNN}，每一层只有一个单元，并且在每个\gls{hidden_layer}不使用\gls{activation_function}：$\hat{y} = xw_1 w_2 w_3 \dots w_l$。
此处，$w_i$表示用于层$i$的权重。层$i$的输出是$h_i = h_{i-1} w_i$。
输出$\hat{y}$是输入$x$的线性函数，但是权重$w_i$的非线性函数。
假设我们的\gls{cost_function} $\hat{y}$上的梯度为$1$，所以我们希望稍稍降低$\hat{y}$。
然后\gls{backward_propagation}算法可以计算梯度$\Vg = \nabla_{\Vw} \hat{y}$。
想想我们在更新$\Vw \leftarrow \Vw - \epsilon \Vg$时会发生什么。
近似$\hat{y}$的一阶泰勒级数会预测$\hat{y}$的值下降$\epsilon \Vg^\top \Vg$。
如果我们希望$\hat{y}$下降$0.1$，那么梯度中的一阶信息表明我们应设置\gls{learning_rate}$\epsilon$为$\frac{0.1}{\Vg^\top \Vg}$。
然而，实际的更新将包括二阶，三阶，直到$l$阶的影响。
$\hat{y}$的更新值为
\begin{equation}
    x(w_1-\epsilon g_1)(w_2-\epsilon g_2)\dots(w_l-\epsilon g_l),
\end{equation}
这个更新中所产生的一个二阶项示例是$\epsilon^2 g_1 g_2 \prod_{i=3}^l w_i$ 。
如果 $\prod_{i=3}^l w_i$很小，那么该项可以忽略不计。而如果层$3$到层$l$的权重都比$1$大时，该项可能会指数级大。
这使得我们很难选择一个合适的\gls{learning_rate}，因为某一层中参数更新的效果很大程度上取决于其他所有层。
二阶优化算法通过考虑二阶相互影响来解决这个问题，但我们可以看到，在非常深的网络中，更高阶的相互影响会很显著。
即使是二阶优化算法，计算代价也很高，并且通常需要大量近似，以免真正计算所有的重要二阶相互作用。
因此对于$n>2$的情况，建立$n$阶优化算法似乎是无望的。
那么我们可以做些什么呢？

% -- 309 --

\gls{batch_normalization}提出了一种几乎可以重参数化所有\gls{deep_network}的优雅方法。
重参数化显著减少了多层之间协调更新的问题。
\gls{batch_normalization}可应用于网络的任何输入层或\gls{hidden_layer}。
设$\MH$是需要标准化的某层的\gls{minibatch}\gls{activation_function}，排布为设计矩阵，每个样本的激活出现在矩阵的每一行中。
为了标准化$\MH$，我们将其替换为
\begin{equation}
\MH' = \frac{\MH - \Vmu}{\Vsigma},
\end{equation}
其中$\Vmu$是包含每个单元均值的向量，$\Vsigma$是包含每个单元标准差的向量。
此处的算术是基于广播向量$\Vmu$和向量$\Vsigma$应用于矩阵$\MH$的每一行。
在每一行内，运算是逐元素的，因此$H_{i,j}$标准化为减去$\mu_j$再除以$\sigma_j$。
网络的其余部分操作$\MH'$的方式和原网络操作$\MH$的方式一样。

在训练阶段，
\begin{equation}
    \Vmu = \frac{1}{m} \sum_i \MH_{i,:}
\end{equation}
和
\begin{equation}
    \Vsigma = \sqrt{ \delta + \frac{1}{m} \sum_i (\MH - \Vmu)_i^2 },
\end{equation}
其中$\delta$是个很小的正值，比如$10^{-8}$，以强制避免遇到$\sqrt{z}$的梯度在$z=0$处未定义的问题。
至关重要的是，\emph{我们反向传播这些操作}，来计算均值和标准差，并应用它们于标准化$\MH$。
这意味着，梯度不会再简单地增加$h_i$的\gls{standard_deviation}或均值；标准化操作会除掉这一操作的影响，归零其在梯度中的元素。
这是\gls{batch_normalization}方法的一个重大创新。
以前的方法添加\gls{cost_function}的惩罚，以鼓励单元标准化激活统计量，或是在每个\gls{GD}步骤之后重新标准化单元统计量。
前者通常会导致不完全的标准化，而后者通常会显著地消耗时间，因为学习算法会反复改变均值和方差而标准化步骤会反复抵消这种变化。
\gls{batch_normalization}重参数化模型，以使一些单元总是被定义标准化，巧妙地回避了这两个问题。

% -- 310 --

在测试阶段，$\Vmu$和$\Vsigma$可以被替换为训练阶段收集的运行均值。
这使得模型可以对单一样本评估，而无需使用定义于整个\gls{minibatch}的$\Vmu$和$\Vsigma$。

回顾例子$\hat{y} = x w_1 w_2 \dots w_l$，我们看到，我们可以通过标准化$h_{l-1}$很大程度地解决了学习这个模型的问题。
假设$x$采样自一个单位高斯。
那么$h_{l-1}$也是来自高斯，因为从$x$到$h_l$的变换是线性的。
然而，$h_{l-1}$不再有零均值和单位方差。
使用\gls{batch_normalization}后，我们得到的归一化$\hat{h}_{l-1}$恢复了零均值和单位方差的特性。
对于底层的几乎任意更新而言，$\hat{h}_{l-1}$仍然保持着单位高斯。
然后输出$\hat{y}$可以学习为一个简单的线性函数$\hat{y} = w_l \hat{h}_{l-1}$。
现在学习这个模型非常简单，因为低层的参数在大多数情况下没有什么影响；它们的输出总是重新标准化为单位高斯。
只在少数个例中，低层会有影响。
改变某个低层权重为$0$，可能使输出退化；改变低层权重的符号可能反转$\hat{h}_{l-1}$和$y$之间的关系。
这些情况都是非常罕见的。
没有标准化，几乎每一个更新都会对$h_{l-1}$的统计量有着极端的影响。
因此，\gls{batch_normalization}显著地使得模型更易学习。
在这个示例中，容易学习的代价是使得底层网络没有用。
在我们的线性示例中，较低层不再有任何有害的影响，但它们也不再有任何有益的影响。
这是因为我们已经标准化了一阶和二阶统计量，这是线性网络可以影响的所有因素。
在具有非线性\gls{activation_function}的\gls{DNN}中，较低层可以进行数据的非线性变换，所以它们仍然是有用的。
\gls{batch_normalization}仅标准化每个单元的均值和方差，以稳定化学习，但允许单元和单个单元的非线性统计量之间的关系发生变化。

由于网络的最后一层能够学习线性变换，实际上我们可能希望移除一层内单元之间的所有线性关系。
事实上，这是~\cite{Desjardins2015}中采用的方法，为\gls{batch_normalization}提供了灵感。
令人遗憾的是，消除所有的线性关联比标准化各个独立单元的均值和\gls{standard_deviation}代价更高，因此\gls{batch_normalization}仍是迄今最实用的方法。

% -- 311 --

标准化一个单元的均值和标准差会降低包含该单元的\gls{NN}的表达能力。
为了保持网络的表现力，通常会将\gls{batch}\gls{hidden_unit}激活$\MH$替换为$\gamma \MH' + \Vbeta$，而不是简单地使用标准化的$\MH'$。
变量$\Vgamma$和$\Vbeta$是允许新变量有任意均值和\gls{standard_deviation}的学习参数。
乍一看，这似乎是无用的——为什么我们将均值设为$0$，然后又引入参数允许它被重设为任意值$\Vbeta$？
答案是新的参数可以表示旧参数作为输入的同一族函数，但是新参数有不同的学习动态。
在旧参数中，$\MH$的均值取决于$\MH$下层中参数的复杂关联。
在新参数中，$\Vgamma \MH' + \Vbeta$的均值仅由$\Vbeta$确定。
新参数很容易通过\gls{GD}来学习。

大多数\gls{NN}层会采取$\phi(\MX\MW+ \Vb)$的形式，其中$\phi$是某个固定的非线性\gls{activation_function}，如\gls{rectified_linear}变换。
自然想到我们应该将\gls{batch_normalization}应用于输入$\MX$还是变换后的值$\MX\MW+\Vb$。
\cite{Ioffe+Szegedy-2015}推荐后者。
更具体地，$\MX\MW+\Vb$应替换为$\MX\MW$的标准化形式。
偏置项应被忽略，因为参数$\Vbeta$会加入\gls{batch_normalization}重参数化，它是冗余的。
一层的输入通常是前一层的非线性\gls{activation_function}（如\gls{rectified_linear}函数）的输出。
因此，输入的统计量更符合非高斯，而更不服从线性操作的标准化。

\chapref{chap:convolutional_networks}所述的卷积网络，在特征映射中每个空间位置同样地标准化$\Vmu$和$\Vsigma$是很重要的，能使特征映射的统计量在不同的空间位置，仍然保持相同。

\subsection{坐标下降}
\label{sec:coordinate_descent}
在某些情况下，将一个优化问题分解成几个部分，可以更快地解决原问题。
如果我们相对于某个单一变量$x_i$最小化$f(\Vx)$，然后相对于另一个变量$x_j$等等，反复循环所有的变量，我们会保证到达（局部）极小值。
这种做法被称为\firstgls{coordinate_descent}，因为我们一次优化一个坐标。
更一般地，\firstgls{block_coordinate_descent}是指对于某个子集的变量同时最小化。
术语``\gls{coordinate_descent}''通常既指块坐标下降，也指严格的单个坐标下降。

% -- 312 --

当优化问题中的不同变量能够清楚地分成相对独立的组，或是当优化一组变量明显比优化所有变量效率更高时，坐标下降最有意义。
例如，考虑\gls{cost_function}
\begin{equation}
    J(\MH, \MW) = \sum_{i,j} |H_{i,j}| + \sum_{i,j} \left( \MX - \MW^\top \MH \right)_{i,j}^2 .
\end{equation}
该函数描述了一种被称为\gls{sparse_coding}的学习问题，其目标是寻求一个权重矩阵$\MW$，可以线性解码激活值矩阵$\MH$以重构\gls{training_set}$\MX$。
\gls{sparse_coding}的大多数应用还涉及到\gls{weight_decay}或$\MW$列范数的约束，以避免极小$\MH$和极大$\MW$的病态解。

函数$J$不是凸的。
然而，我们可以将训练算法的输入分成两个集合：字典参数$\MW$和编码表示$\MH$。
最小化关于这两者之一的任意一组变量的\gls{objective_function}都是凸问题。
因此，块坐标下降允许我们使用高效的\gls{convex_optimization}算法，交替固定$\MH$优化$\MW$和固定$\MW$优化$\MH$。

当一个变量的值很大程度地影响另一个变量的最优值时，坐标下降不是一个很好的方法，如函数$f(\Vx)=(x_1 - x_2)^2+\alpha(x_1^2 + x_2^2)$，其中$\alpha$是正值常数。
第一项鼓励两个变量具有相似的值，而第二项鼓励它们接近零。
解是两者都为零。
\gls{newton_method}可以一步解决这个问题，因为它是一个正定二次问题。
但是，对于小值$\alpha$而言，坐标下降会使进展非常缓慢，因为第一项不允许单个变量变为和其他变量当前值显著不同的值。


\subsection{Polyak平均}
\label{sec:polyak_averaging}
Polyak平均\citep{Polyak+Juditsky-1992}会平均优化算法在参数空间访问轨迹中的几个点。
如果$t$次迭代\gls{GD}访问了点$\Vtheta^{(1)},\dots,\Vtheta^{(t)}$，那么Polyak平均算法的输出是$\hat{\Vtheta}^{(t)} = \frac{1}{t} \sum_i \Vtheta^{(i)}$。
在某些问题中，如\gls{GD}应用于凸问题时，这种方法具有较强的收敛保证。
当应用于\gls{NN}时，其验证更多是启发式的，但在实践中表现良好。
基本想法是，优化算法可能会来回穿过山谷好几次而没经过山谷底部附近的点。
尽管两边所有位置的均值应比较接近谷底。

% -- 313 --

在\gls{nonconvex}问题中，优化轨迹的路径可以非常复杂，并且经过了许多不同的区域。
包括参数空间中遥远过去的点，可能与当前点在\gls{cost_function}上相隔很大的障碍，看上去不像一个有用的行为。
其结果是，当应用Polyak平均于\gls{nonconvex}问题时，通常会使用指数衰减计算平均值：
\begin{equation}
    \hat{\Vtheta}^{(t)} = \alpha \hat{\Vtheta}^{(t-1)} + (1-\alpha) \Vtheta^{(t)} .
\end{equation}

这个计算平均值的方法被用于大量数值应用中。最近的例子请查看\cite{Szegedy-et-al-2015}。

\subsection{监督\glsentrytext{pretraining}}
\label{sec:supervised_pretraining}
有时，如果模型太复杂难以优化，或是如果任务非常困难，直接训练模型来解决特定任务的挑战可能太大。
有时训练一个较简单的模型来求解问题，然后使模型更复杂会更有效。
训练模型来求解一个简化的问题，然后转移到最后的问题，有时也会更有效些。
这些在直接训练目标模型求解目标问题之前，训练简单模型求解简化问题的方法统称为\firstgls{pretraining}。


\firstgls{greedy_algorithm}将问题分解成许多部分，然后独立地在每个部分求解最优值。
令人遗憾的是，结合各个最佳的部分不能保证得到一个最佳的完整解。
然而，贪心算法计算上比求解最优联合解的算法高效得多，并且贪心算法的解在不是最优的情况下，往往也是可以接受的。
贪心算法也可以紧接一个\firstgls{fine_tuning}阶段，联合优化算法搜索全问题的最优解。
使用贪心解初始化联合优化算法，可以极大地加速算法，并提高寻找到的解的质量。

\gls{pretraining}算法，特别是贪心\gls{pretraining}，在\gls{DL}中是普遍存在的。
在本节中，我们会具体描述这些将监督学习问题分解成其他简化的监督学习问题的\gls{pretraining}算法。
这种方法被称为\firstgls{greedy_supervised_pretraining}。

% -- 314 --

在\gls{greedy_supervised_pretraining}的原始版本\citep{Bengio-nips-2006-short}中，每个阶段包括一个仅涉及最终\gls{NN}的子集层的监督学习训练任务。
\gls{greedy_supervised_pretraining}的一个例子如\figref{fig:chap8_deep_sup}所示，其中每个附加的\gls{hidden_layer}作为浅层监督\gls{MLP}的一部分\gls{pretraining}，以先前训练的\gls{hidden_layer}输出作为输入。
\cite{Simonyan2015}~\gls{pretraining}深度卷积网络（11层权重），然后使用该网络前四层和最后三层初始化更深的网络（多达19层权重），并非一次\gls{pretraining}一层。
非常深的新网络的中间层是随机初始化的。
然后联合训练新网络。
还有一种选择，由\cite{Yu+al-2010}提出，将先前训练\gls{MLP}的\emph{输出}，以及原始输入，作为每个附加阶段的输入。

\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter8/figures/deep_sup}}
\fi
\caption{一种形式的\gls{greedy_supervised_pretraining}的示意图~\citep{Bengio-nips-2006-small}。
(a)我们从训练一个足够浅的架构开始。
(b)同一个架构的另一描绘。
(c)我们只保留原始网络的输入到隐藏层，并丢弃隐藏到输出层。 
我们将第一层\gls{hidden_layer}的输出作为输入发送到另一监督单隐层\,\glssymbol{MLP}（使用与第一个网络相同的目标训练），从而可以添加第二层\gls{hidden_layer}。 
这可以根据需要重复多层。
(d)所得架构的另一种描绘，可视为\gls{feedforward_network}。 
为了进一步改进优化，我们可以联合地\gls{fine_tuning}所有层（仅在该过程的结束或者该过程的每个阶段）。
}
\label{fig:chap8_deep_sup}
\end{figure}


为什么\gls{greedy_supervised_pretraining}会有帮助呢？
最初由~\cite{Bengio-nips-2006}提出的假说是，其有助于更好地指导深层结构的中间层的学习。
一般情况下，\gls{pretraining}对于优化和\gls{generalization}都是有帮助的。

另一个与监督\gls{pretraining}有关的方法扩展了迁移学习的想法：\cite{yosinski-nips2014}在一组任务上\gls{pretraining}了$8$层权重的深度卷积网络（1000个ImageNet对象类的子集），然而用该网络的前$k$层初始化同样规模的网络。
然后第二个网络的所有层（上层随机初始化）联合训练以执行不同的任务（1000个ImageNet对象类的另一个子集），但训练样本少于第一个任务。
\gls{NN}中另一个和迁移学习相关的方法将在\secref{sec:transfer_learning_and_domain_adaptation}讨论。

另一条相关的工作线是\textbf{FitNets}~\citep{Romero-et-al-ICLR2015-small}方法。
这种方法始于训练深度足够低和宽度足够大（每层单元数），容易训练的网络。
然后，这个网络成为第二个网络（被指定为\,\textbf{学生}）的\,\textbf{老师}。
学生网络更深更窄（11至19层），且在正常情况下很难用SGD训练。
训练学生网络不仅需要预测原任务的输出，还需要预测教师网络中间层的值，这样使得训练学生网络变得更容易。
这个额外的任务说明了\gls{hidden_layer}应如何使用，并且能够简化优化问题。
附加参数被引入来从更深的学生网络中间层去回归$5$层教师网络的中间层。
然而，该目标是预测教师网络的中间\gls{hidden_layer}，并非预测最终分类目标。
学生网络的低层因而具有两个目标：帮助学生网络的输出完成其目标和预测教师网络的中间层。
尽管一个窄而深的网络似乎比宽而浅的网络更难训练，但窄而深网络的泛化能力可能更好，
并且如果其足够窄，参数足够少，那么其计算代价更小。
没有\gls{hidden_layer}的提示，学生网络在\gls{training_set}和\gls{test_set}上的实验表现都很差。
因而中间层的提示是有助于训练很难训练的网络的方法之一，但是其他优化技术或是架构上的变化也可能解决这个问题。

% -- 316 --

\subsection{设计有助于优化的模型}
\label{sec:designing_models_to_aid_optimization}
改进优化的最好方法并不总是改进优化算法。
相反，\gls{deep_model}中优化的许多改进来自于设计易于优化的模型。

原则上，我们可以使用呈锯齿非单调模式上上下下的\gls{activation_function}，但是，这将使优化极为困难。
在实践中，\emph{选择一族容易优化的模型比使用一个强大的优化算法更重要}。
\gls{NN}学习在过去30年的大多数进步主要来自于改变模型族，而非改变优化过程。
1980年代用于训练\gls{NN}的带\gls{momentum}的\gls{SGD}，仍然是现代\gls{NN}应用中的前沿算法。

具体来说，现代\gls{NN}的\emph{设计选择}体现在层之间的线性变换，几乎处处可导的\gls{activation_function}，和大部分定义域都有明显的梯度。
特别地，创新的模型，如\,\glssymbol{LSTM}，\gls{ReLU}和\,\gls{maxout}\,单元都比先前的模型（如基于\,\gls{sigmoid}\,单元的\gls{deep_network}）使用更多的线性函数。
这些模型都具有简化优化的性质。
如果线性变换的\,\gls{jacobian}\,具有相对合理的奇异值，那么梯度能够流经很多层。
此外，线性函数在一个方向上一致增加，所以即使模型的输出远离正确值，也可以简单清晰地计算梯度，使其输出方向朝降低\gls{loss_function}的方向移动。
换言之，现代\gls{NN}的设计方案旨在使其\emph{局部}梯度信息合理地对应着移向一个遥远的解。

其他的模型设计策略有助于使优化更简单。
例如，层之间的线性路径或是跳跃连接减少了从较低层参数到输出最短路径的长度，因而缓解了梯度消失的问题\citep{Srivastava-et-al-arxiv2015}。
一个和跳跃连接相关的想法是添加和网络中间\gls{hidden_layer}相连的输出的额外副本，如GoogLeNet~\citep{Szegedy-et-al-arxiv2014}和深度监督网络\citep{Lee-et-al-2014}。
这些``辅助头''被训练来执行和网络顶层主要输出相同的任务，以确保底层网络能够接受较大的梯度。
当训练完成时，辅助头可能被丢弃。
这是之前小节介绍到的\gls{pretraining}策略的替代方法。
以这种方式，我们可以在一个阶段联合训练所有层，而不改变架构，使得中间层（特别是低层）能够通过更短的路径得到一些如何更新的有用信息。
这些信息为底层提供了误差信号。

% -- 317 --

\subsection{\glsentrytext{continuation_method}和\glsentrytext{curriculum_learning}}
\label{sec:continuation_methods_and_curriculum_learning}
正如\secref{sec:poor_correspondence_between_local_and_global_structure}探讨的，许多优化挑战都来自于\gls{cost_function}的全局结构，不能仅通过局部更新方向上更好的估计来解决。
解决这个问题的主要方法是尝试初始化参数到某种区域内，该区域可以通过局部下降很快连接到参数空间中的解。


\firstgls{continuation_method}是一族通过挑选初始点使优化更容易的方法，以确保局部优化花费大部分时间在表现良好的空间。
\gls{continuation_method}的背后想法是构造一系列具有相同参数的\gls{objective_function}。
为了最小化\gls{cost_function} $J(\Vtheta)$，我们构建新的\gls{cost_function} $\{J^{(0)},\dots,J^{(n)}\}$。
这些\gls{cost_function}的难度逐步提高，其中$J^{(0)}$是最容易最小化的，$J^{(n)}$是最难的，真正的\gls{cost_function}驱动整个过程。
当我们说$J^{(i)}$比$J^{(i+1)}$更容易时，是指其在更多的$\Vtheta$空间上表现良好。
随机初始化更有可能落入局部下降可以成功最小化\gls{cost_function}的区域，因为其良好区域更大。
这系列\gls{cost_function}设计为前一个解是下一个的良好初始点。
因此，我们首先解决一个简单的问题，然后改进解以解决逐步变难的问题，直到我们求解真正问题的解。

传统的\gls{continuation_method}（用于\gls{NN}训练之前的\gls{continuation_method}）通常基于平滑\gls{objective_function}。
读者可以查看~\cite{Wu-97}了解这类方法的示例，以及一些相关方法的综述。
\gls{continuation_method}也和参数中加入\gls{noise}的模拟退火紧密相关\citep{Kirkpatrick83}。
\gls{continuation_method}在最近几年非常成功。
参考~\cite{Mobahi+Fisher-AAAI2015}了解近期文献的概述，特别是在~\glssymbol{AI}~方面的应用。

% -- 318 --

传统上，\gls{continuation_method}主要用来克服\gls{local_minima}的问题。
具体地，它被设计来在有很多\gls{local_minima}的情况下，求解一个\gls{global_minimum}。
这些连续方法会通过``模糊''原来的\gls{cost_function}来构建更容易的\gls{cost_function}。
这些模糊操作可以是用采样来近似
\begin{equation}
    J^{(i)}(\Vtheta) = \SetE_{\theta' \sim \mathcal{N}(\Vtheta'; \Vtheta, \sigma^{(i)2})} J(\Vtheta')
\end{equation}
这个方法的直觉是有些\gls{nonconvex}函数在模糊后会近似凸的。
在许多情况下，这种模糊保留了关于全局极小值的足够信息，我们可以通过逐步求解模糊更少的问题来求解全局极小值。
这种方法有三种可能失败的方式。
首先，它可能成功地定义了一连串\gls{cost_function}，并从开始的一个凸函数起（逐一地）沿着函数链最佳轨迹逼近全局最小值，但可能需要非常多的逐步\gls{cost_function}，整个过程的成本仍然很高。
另外，即使\gls{continuation_method}可以适用，NP-hard的优化问题仍然是NP-hard。
其他两种\gls{continuation_method}失败的原因是不实用。
其一，不管如何模糊，函数都没法变成凸的，比如函数$J(\Vtheta) = -\Vtheta^\top \Vtheta$。
其二，函数可能在模糊后是凸的，但模糊函数的最小值可能会追踪到一个局部最小值，而非原始\gls{cost_function}的全局最小值。


尽管\gls{continuation_method}最初用来解决局部最小值的问题，而局部最小值已不再认为是\gls{NN}优化中的主要问题了。
幸运的是，\gls{continuation_method}仍然有所帮助。
\gls{continuation_method}引入的简化\gls{objective_function}能够消除平坦区域，减少梯度估计的方差，提高\,\gls{hessian}\,矩阵的条件数，使局部更新更容易计算，或是改进局部更新方向与朝向全局解方向之间的对应关系。

\cite{Bengio+al-2009}指出被称为\firstgls{curriculum_learning}或者\firstgls{shaping}的方法可以被解释为\gls{continuation_method}。
\gls{curriculum_learning}基于规划学习过程的想法，首先学习简单的概念，然后逐步学习依赖于这些简化概念的复杂概念。
之前这一基本策略被用来加速动物训练过程\citep{Skinner1958,Peterson2004,Krueger+Dayan-2009}和\gls{ML}过程\citep{solomonoff1989system,Elman93,Sanger-1994}。
\cite{Bengio+al-2009}验证这一策略为\gls{continuation_method}，通过增加简单样本的影响（通过分配它们较大的系数到\gls{cost_function}，或者更频繁地采样），先前的$J^{(i)}$会变得更容易。
实验证明，在大规模的神经语言模型任务上使用\gls{curriculum_learning}，可以获得更好的结果。
课程学习已经成功应用于大量的自然语言\citep{Spitkovsky-et-al-HLT2010,collobert2011natural,Mikolov-ASRU-2011,Tu+Honavar-IJCAI2011}和计算机视觉\citep{Kumar+al-2010,Lee+Grauman-CVPR2011,Supancic+Ramanan-CVPR2013}任务上。
\gls{curriculum_learning}被证实为与人类教学方式一致\citep{Khan+Zhu+Mutlu-2011}：
教师刚开始会展示更容易、更典型的示例，然后帮助学习者在不太显然的情况下提炼决策面。
在人类教学上，基于\gls{curriculum_learning}的策略比基于样本均匀采样的策略\emph{更有效}，也能提高其他学习策略的效率\citep{Basu+Christensen-AAAI2013}。

% -- 319 --

\gls{curriculum_learning}研究的另一个重要贡献体现在训练循环\gls{NN}捕获长期依赖：
\cite{Zaremba+Sutskever-arxiv2014}发现使用\emph{\gls{stochastic_curriculum}}获得了更好的结果，其中容易和困难的示例混合在一起，随机提供给学习者，更难示例（这些具有长期依赖）的平均比例在逐渐上升。
而使用确定性课程，并没有发现超过基线（完整\gls{training_set}的普通训练）的改进。

现在我们已经介绍了一些基本的\gls{NN}模型，以及如何进行正则化和优化。
在接下来的章节中，我们转向特化的\gls{NN}家族，允许其扩展到能够处理很大规模的数据和具有特殊结构的数据。
在本章中讨论的优化算法在较少改动后或者无需改动，通常就可以直接用于这些特化的架构。

% -- 320 --
